Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix bug where obj.should_receive(:foo).with(stub.as_null_object) would

pass with a false positive.

- Closes #233.
  • Loading branch information...
commit 1ba73c96e960edaeec72d7f0827b521b69d5374b 1 parent 880a2ae
@dchelimsky dchelimsky authored
View
15 lib/rspec/mocks/argument_expectation.rb
@@ -9,9 +9,10 @@ def initialize(*args, &block)
@match_any_args = false
@matchers = nil
- if ArgumentMatchers::AnyArgsMatcher === args.first
+ case args.first
+ when ArgumentMatchers::AnyArgsMatcher
@match_any_args = true
- elsif ArgumentMatchers::NoArgsMatcher === args.first
+ when ArgumentMatchers::NoArgsMatcher
@matchers = []
else
@matchers = args.collect {|arg| matcher_for(arg)}
@@ -19,13 +20,17 @@ def initialize(*args, &block)
end
def matcher_for(arg)
- return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg)
- return ArgumentMatchers::RegexpMatcher.new(arg) if arg.is_a?(Regexp)
+ return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg)
+ return ArgumentMatchers::RegexpMatcher.new(arg) if arg.is_a?(Regexp)
return ArgumentMatchers::EqualityProxy.new(arg)
end
def is_matcher?(obj)
- return obj.respond_to?(:matches?) & obj.respond_to?(:description)
+ !is_stub_as_null_object?(obj) & obj.respond_to?(:matches?) & obj.respond_to?(:description)
+ end
+
+ def is_stub_as_null_object?(obj)
+ obj.respond_to?(:__rspec_double_acting_as_null_object?) && obj.__rspec_double_acting_as_null_object?
end
def args_match?(*args)
View
10 spec/rspec/mocks/argument_expectation_spec.rb
@@ -6,16 +6,18 @@ module Mocks
it "considers an object that responds to #matches? and #description to be a matcher" do
argument_expecatation = RSpec::Mocks::ArgumentExpectation.new
obj = double("matcher")
- obj.should_receive(:respond_to?).with(:matches?).and_return(true)
- obj.should_receive(:respond_to?).with(:description).and_return(true)
+ obj.stub(:respond_to?).with(:__rspec_double_acting_as_null_object?).and_return(false)
+ obj.stub(:respond_to?).with(:matches?).and_return(true)
+ obj.stub(:respond_to?).with(:description).and_return(true)
argument_expecatation.is_matcher?(obj).should be_true
end
it "does NOT consider an object that only responds to #matches? to be a matcher" do
argument_expecatation = RSpec::Mocks::ArgumentExpectation.new
obj = double("matcher")
- obj.should_receive(:respond_to?).with(:matches?).and_return(true)
- obj.should_receive(:respond_to?).with(:description).and_return(false)
+ obj.stub(:respond_to?).with(:__rspec_double_acting_as_null_object?).and_return(false)
+ obj.stub(:respond_to?).with(:matches?).and_return(true)
+ obj.stub(:respond_to?).with(:description).and_return(false)
argument_expecatation.is_matcher?(obj).should be_false
end
end
View
24 spec/rspec/mocks/mock_spec.rb
@@ -635,6 +635,30 @@ def add_call
@mock.rspec_reset
end
end
+
+ context "with non-matching doubles" do
+ it "fails" do
+ d1 = double('1')
+ d2 = double('2')
+ @mock.should_receive(:foo).with(d1)
+ expect do
+ @mock.foo(d2)
+ end.to raise_error
+ @mock.rspec_reset
+ end
+ end
+
+ context "with non-matching doubles as_null_object" do
+ it "fails" do
+ d1 = double('1').as_null_object
+ d2 = double('2').as_null_object
+ @mock.should_receive(:foo).with(d1)
+ expect do
+ @mock.foo(d2)
+ end.to raise_error
+ @mock.rspec_reset
+ end
+ end
end
context "with a block" do
Please sign in to comment.
Something went wrong with that request. Please try again.