Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change method dispatch behavior to that of jmock2 #395

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ Maybe, but probably not. Partial mocking changes the state of objects in the `Ob

Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The `Expectation#stubs` method is syntactic sugar to make the intent of the test more explicit.

When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations.
When a method is invoked on a mock object, the Mockery searches through its expectations from oldest to newest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations.

See the [documentation](https://mocha.jamesmead.org/Mocha/Mock.html) for `Mocha::Mock` for further details.

Expand Down
2 changes: 1 addition & 1 deletion lib/mocha/expectation_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def initialize(expectations = [])
end

def add(expectation)
@expectations.unshift(expectation)
@expectations.push(expectation)
expectation
end

Expand Down
19 changes: 6 additions & 13 deletions lib/mocha/mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,27 @@ module Mocha
# expectation of zero or more invocations. The {#stubs} method is syntactic
# sugar to make the intent of the test more explicit.
#
# When a method is invoked on a mock object, the mock object searches through
# its expectations from newest to oldest to find one that matches the
# When a method is invoked on a mock object, the Mockery searches through
# its expectations from oldest to newest to find one that matches the
# invocation. After the invocation, the matching expectation might stop
# matching further invocations. For example, an +expects(:foo).once+
# expectation only matches once and will be ignored on future invocations
# while an +expects(:foo).at_least_once+ expectation will always be matched
# against invocations.
#
# This scheme allows you to:
#
# - Set up default stubs in your the +setup+ method of your test class and
# override some of those stubs in individual tests.
# - Set up different +once+ expectations for the same method with different
# action per invocation. However, it's better to use the
# This scheme allows you to set up different expectations for the same method
# with different action per invocation. However, it's better to use the
# {Expectation#returns} method with multiple arguments to do this, as
# described below.
#
# However, there are some possible "gotchas" caused by this scheme:
#
# - if you create an expectation and then a stub for the same method, the
# - if you create a stub and then an expectation for the same method, the
# stub will always override the expectation and the expectation will never
# be met.
# - if you create a stub and then an expectation for the same method, the
# - if you create an expectation and then a stub for the same method, the
# expectation will match, and when it stops matching the stub will be used
# instead, possibly masking test failures.
# - if you create different expectations for the same method, they will be
# invoked in the opposite order than that in which they were specified,
# rather than the same order.
#
# The best thing to do is not set up multiple expectations and stubs for the
# same method with exactly the same matchers. Instead, use the
Expand Down
52 changes: 26 additions & 26 deletions test/acceptance/mocked_methods_dispatch_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,64 +11,64 @@ def teardown
teardown_acceptance_test
end

def test_should_find_latest_matching_expectation
def test_should_find_oldest_matching_expectation
test_result = run_as_test do
mock = mock()
mock.stubs(:method).returns(1)
mock.stubs(:method).returns(2)
assert_equal 2, mock.method
assert_equal 2, mock.method
assert_equal 2, mock.method
assert_equal 1, mock.method
assert_equal 1, mock.method
assert_equal 1, mock.method
end
assert_passed(test_result)
end

def test_should_find_latest_expectation_which_has_not_stopped_matching
def test_should_find_oldest_expectation_which_has_not_stopped_matching
test_result = run_as_test do
mock = mock()
mock.stubs(:method).returns(1)
mock.stubs(:method).once.returns(2)
assert_equal 2, mock.method
assert_equal 1, mock.method
mock.stubs(:method).once.returns(1)
mock.stubs(:method).returns(2)
assert_equal 1, mock.method
assert_equal 2, mock.method
assert_equal 2, mock.method
end
assert_passed(test_result)
end

def test_should_keep_finding_later_stub_and_so_never_satisfy_earlier_expectation
def test_should_keep_finding_older_stub_and_so_never_satisfy_earlier_expectation
responses = []
test_result = run_as_test do
mock = mock()
mock.expects(:method).returns(1)
mock.stubs(:method).returns(2)
assert_equal 2, mock.method
assert_equal 2, mock.method
assert_equal 2, mock.method
mock.stubs(:method).returns(1)
mock.expects(:method).returns(2)
3.times { responses << mock.method }
end
assert_equal [1, 1, 1], responses
assert_failed(test_result)
end

def test_should_find_later_expectation_until_it_stops_matching_then_find_earlier_stub
def test_should_find_older_expectation_until_it_stops_matching_then_find_earlier_stub
test_result = run_as_test do
mock = mock()
mock.stubs(:method).returns(1)
mock.expects(:method).returns(2)
assert_equal 2, mock.method
assert_equal 1, mock.method
mock.expects(:method).returns(1)
mock.stubs(:method).returns(2)
assert_equal 1, mock.method
assert_equal 2, mock.method
assert_equal 2, mock.method
end
assert_passed(test_result)
end

def test_should_find_latest_expectation_with_range_of_expected_invocation_count_which_has_not_stopped_matching
def test_should_find_oldest_expectation_with_range_of_expected_invocation_count_which_has_not_stopped_matching
test_result = run_as_test do
mock = mock()
mock.stubs(:method).returns(1)
mock.stubs(:method).times(2..3).returns(2)
assert_equal 2, mock.method
assert_equal 2, mock.method
assert_equal 2, mock.method
mock.stubs(:method).times(2..3).returns(1)
mock.stubs(:method).returns(2)
assert_equal 1, mock.method
assert_equal 1, mock.method
assert_equal 1, mock.method
assert_equal 2, mock.method
assert_equal 2, mock.method
end
assert_passed(test_result)
end
Expand Down
4 changes: 2 additions & 2 deletions test/acceptance/multiple_expectations_failure_message_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def test_should_report_multiple_satisfied_expectations
'unsatisfied expectations:',
'- expected exactly 3 times, invoked twice: #<Mock:mock>.method_three(any_parameters)',
'satisfied expectations:',
'- expected exactly twice, invoked twice: #<Mock:mock>.method_two(any_parameters)',
'- expected exactly once, invoked once: #<Mock:mock>.method_one(any_parameters)'
'- expected exactly once, invoked once: #<Mock:mock>.method_one(any_parameters)',
'- expected exactly twice, invoked twice: #<Mock:mock>.method_two(any_parameters)'
], test_result.failure_message_lines
end
end
4 changes: 2 additions & 2 deletions test/unit/expectation_list_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ def test_should_remove_all_expectations_matching_method_name
assert_same expectation3, expectation_list.match(Invocation.new(:irrelevant, :method_two))
end

def test_should_find_most_recent_matching_expectation
def test_should_find_oldest_matching_expectation
expectation_list = ExpectationList.new
expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
expectation2 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
expectation_list.add(expectation1)
expectation_list.add(expectation2)
assert_same expectation2, expectation_list.match(Invocation.new(:irrelevant, :my_method, :argument1, :argument2))
assert_same expectation1, expectation_list.match(Invocation.new(:irrelevant, :my_method, :argument1, :argument2))
end

def test_should_find_matching_expectation_allowing_invocation
Expand Down
16 changes: 8 additions & 8 deletions test/unit/mock_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,32 +200,32 @@ def test_should_keep_returning_specified_value_for_expects
assert_equal 1, mock.method1
end

def test_should_match_most_recent_call_to_expects
def test_should_match_oldest_call_to_expects
mock = build_mock
mock.expects(:method1).returns(0)
mock.expects(:method1).returns(1)
assert_equal 1, mock.method1
assert_equal 0, mock.method1
end

def test_should_match_most_recent_call_to_stubs
def test_should_match_oldest_call_to_stubs
mock = build_mock
mock.stubs(:method1).returns(0)
mock.stubs(:method1).returns(1)
assert_equal 1, mock.method1
assert_equal 0, mock.method1
end

def test_should_match_most_recent_call_to_stubs_or_expects
def test_should_match_oldest_call_to_stubs_or_expects
mock = build_mock
mock.stubs(:method1).returns(0)
mock.expects(:method1).returns(1)
assert_equal 1, mock.method1
assert_equal 0, mock.method1
end

def test_should_match_most_recent_call_to_expects_or_stubs
def test_should_match_oldest_call_to_expects_or_stubs
mock = build_mock
mock.expects(:method1).returns(0)
mock.stubs(:method1).returns(1)
assert_equal 1, mock.method1
assert_equal 0, mock.method1
end

def test_should_respond_to_expected_method
Expand Down