diff --git a/lib/rspec/mocks/error_generator.rb b/lib/rspec/mocks/error_generator.rb index e947df7c2..e7ba3cbcc 100644 --- a/lib/rspec/mocks/error_generator.rb +++ b/lib/rspec/mocks/error_generator.rb @@ -27,6 +27,13 @@ def raise_unexpected_message_args_error(expectation, *args) __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}" end + # @private + def raise_missing_default_stub_error(expectation,*args) + expected_args = format_args(*expectation.expected_args) + actual_args = args.collect {|a| format_args(*a)}.join(", ") + __raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n Please stub a default value first if message might be received with other args as well. \n" + end + # @private def raise_similar_message_args_error(expectation, *args) expected_args = format_args(*expectation.expected_args) diff --git a/lib/rspec/mocks/proxy.rb b/lib/rspec/mocks/proxy.rb index 549cfbb1a..b99ff3427 100644 --- a/lib/rspec/mocks/proxy.rb +++ b/lib/rspec/mocks/proxy.rb @@ -129,6 +129,8 @@ def message_received(message, *args, &block) elsif stub = find_almost_matching_stub(message, *args) stub.advise(*args) raise_unexpected_message_args_error(stub, *args) + elsif expectation = find_almost_matching_satisfied_expectation(message,*args) + raise_missing_default_stub_error(expectation, *args) if not null_object? elsif @object.is_a?(Class) @object.superclass.__send__(message, *args, &block) else @@ -146,6 +148,11 @@ def raise_unexpected_message_error(method_name, *args) @error_generator.raise_unexpected_message_error method_name, *args end + # @private + def raise_missing_default_stub_error(expectation, *args) + @error_generator.raise_missing_default_stub_error(expectation, *args) + end + private def method_double @@ -165,6 +172,10 @@ def find_almost_matching_expectation(method_name, *args) method_double[method_name].expectations.find {|expectation| expectation.matches_name_but_not_args(method_name, *args) && !expectation.called_max_times?} end + def find_almost_matching_satisfied_expectation(method_name, *args) + method_double[method_name].expectations.find {|expectation| expectation.matches_name_but_not_args(method_name, *args) } + end + def find_matching_method_stub(method_name, *args) method_double[method_name].stubs.find {|stub| stub.matches?(method_name, *args)} end diff --git a/spec/rspec/mocks/bug_report_123_spec.rb b/spec/rspec/mocks/bug_report_123_spec.rb new file mode 100644 index 000000000..4049936a2 --- /dev/null +++ b/spec/rspec/mocks/bug_report_123_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe 'with' do + it "should ask the user to stub a default value first if the message might be received with other args as well" do + obj = Object.new + obj.should_receive(:foobar).with(1) + obj.foobar(1) + lambda{ obj.foobar(2) }.should raise_error(RSpec::Mocks::MockExpectationError, /Please stub a default value first if message might be received with other args as well./) + end +end