diff --git a/lib/mocha/expectation_setting.rb b/lib/mocha/expectation_setting.rb new file mode 100644 index 000000000..ee829ef10 --- /dev/null +++ b/lib/mocha/expectation_setting.rb @@ -0,0 +1,18 @@ +module Mocha + class ExpectationSetting + attr_reader :expectations + + def initialize(expectations) + @expectations = expectations + end + + %w[ + times twice once never at_least at_least_once at_most at_most_once + with yields multiple_yields returns raises throws then when in_sequence + ].each do |method_name| + define_method(method_name) do |*args, &block| + ExpectationSetting.new(@expectations.map { |e| e.send(method_name, *args, &block) }) + end + end + end +end diff --git a/lib/mocha/mock.rb b/lib/mocha/mock.rb index 44742c5d4..46d65367e 100644 --- a/lib/mocha/mock.rb +++ b/lib/mocha/mock.rb @@ -1,6 +1,7 @@ require 'mocha/singleton_class' require 'mocha/expectation' require 'mocha/expectation_list' +require 'mocha/expectation_setting' require 'mocha/invocation' require 'mocha/names' require 'mocha/receivers' @@ -137,7 +138,7 @@ def expects(method_name_or_hash, backtrace = nil) # object.stubs(:stubbed_method_one).returns(:result_one) # object.stubs(:stubbed_method_two).returns(:result_two) def stubs(method_name_or_hash, backtrace = nil) - anticipates(method_name_or_hash, backtrace) { |expectation| expectation.at_least(0) } + anticipates(method_name_or_hash, backtrace).at_least(0) end # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them. @@ -356,17 +357,16 @@ def any_expectations? end # @private - def anticipates(method_name_or_hash, backtrace = nil, object = Mock.new(@mockery), &block) - Array(method_name_or_hash).map do |*args| + def anticipates(method_name_or_hash, backtrace = nil, object = Mock.new(@mockery)) + ExpectationSetting.new(Array(method_name_or_hash).map do |*args| args = args.flatten method_name = args.shift Mockery.instance.stub_method(object, method_name) unless object.is_a?(Mock) ensure_method_not_already_defined(method_name) expectation = Expectation.new(self, method_name, backtrace) expectation.returns(args.shift) unless args.empty? - yield expectation if block @expectations.add(expectation) - end.last + end) end end end diff --git a/lib/mocha/object_methods.rb b/lib/mocha/object_methods.rb index 8625aac03..a2c7ee851 100644 --- a/lib/mocha/object_methods.rb +++ b/lib/mocha/object_methods.rb @@ -108,7 +108,7 @@ def expects(expected_methods_vs_return_values) # # @see Mock#stubs def stubs(stubbed_methods_vs_return_values) - anticipates(stubbed_methods_vs_return_values) { |expectation| expectation.at_least(0) } + anticipates(stubbed_methods_vs_return_values).at_least(0) end # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them. @@ -143,11 +143,11 @@ def unstub(*method_names) private - def anticipates(expected_methods_vs_return_values, &block) + def anticipates(expected_methods_vs_return_values) if frozen? raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller) end - mocha.anticipates(expected_methods_vs_return_values, caller, self, &block) + mocha.anticipates(expected_methods_vs_return_values, caller, self) end end end diff --git a/test/acceptance/expectations_on_multiple_methods_test.rb b/test/acceptance/expectations_on_multiple_methods_test.rb index fe41f5218..afb5dc3f2 100644 --- a/test/acceptance/expectations_on_multiple_methods_test.rb +++ b/test/acceptance/expectations_on_multiple_methods_test.rb @@ -52,4 +52,29 @@ def my_instance_method_2 end assert_passed(test_result) end + + def test_should_configure_expectations_for_multiple_methods + instance = Class.new do + def my_instance_method_1 + :original_return_value_1 + end + + def my_instance_method_2 + :original_return_value_2 + end + end.new + test_result = run_as_test do + instance.stubs( + :my_instance_method_1 => :new_return_value_1, + :my_instance_method_2 => :new_return_value_2 + ).at_least(2) + assert_equal :new_return_value_1, instance.my_instance_method_1 + assert_equal :new_return_value_2, instance.my_instance_method_2 + end + assert_failed(test_result) + assert_equal [ + "- expected at least twice, invoked once: #{instance.mocha_inspect}.my_instance_method_1(any_parameters)", + "- expected at least twice, invoked once: #{instance.mocha_inspect}.my_instance_method_2(any_parameters)" + ], test_result.failure_message_lines[-2..-1].sort + end end diff --git a/test/unit/mock_test.rb b/test/unit/mock_test.rb index 020c9b618..996873788 100644 --- a/test/unit/mock_test.rb +++ b/test/unit/mock_test.rb @@ -21,7 +21,7 @@ def test_should_build_and_store_expectations mock = build_mock expectation = mock.expects(:method1) assert_not_nil expectation - assert_equal [expectation], mock.__expectations__.to_a + assert_equal expectation.expectations, mock.__expectations__.to_a end def test_should_not_stub_everything_by_default @@ -86,28 +86,14 @@ def test_should_create_and_add_expectations mock = build_mock expectation1 = mock.expects(:method1) expectation2 = mock.expects(:method2) - assert_equal [expectation1, expectation2].to_set, mock.__expectations__.to_set - end - - def test_should_pass_backtrace_into_expectation - mock = build_mock - backtrace = Object.new - expectation = mock.expects(:method1, backtrace) - assert_equal backtrace, expectation.backtrace - end - - def test_should_pass_backtrace_into_stub - mock = build_mock - backtrace = Object.new - stub = mock.stubs(:method1, backtrace) - assert_equal backtrace, stub.backtrace + assert_equal (expectation1.expectations + expectation2.expectations).to_set, mock.__expectations__.to_set end def test_should_create_and_add_stubs mock = build_mock stub1 = mock.stubs(:method1) stub2 = mock.stubs(:method2) - assert_equal [stub1, stub2].to_set, mock.__expectations__.to_set + assert_equal (stub1.expectations + stub2.expectations).to_set, mock.__expectations__.to_set end def test_should_invoke_expectation_and_return_result