diff --git a/features/method_stubs/any_instance.feature b/features/method_stubs/any_instance.feature index 33e58b231..3102ea2be 100644 --- a/features/method_stubs/any_instance.feature +++ b/features/method_stubs/any_instance.feature @@ -37,4 +37,23 @@ Feature: stub on any instance of a class end """ When I run `rspec example_spec.rb` + Then the examples should all pass + + Scenario: any_instance stub with specific arguments matchers + Given a file named "example_spec.rb" with: + """ + describe "any_instance.stub" do + context "with arguments" do + it "returns the stubbed value when arguments match" do + Object.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one) + Object.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two) + + o = Object.new + o.foo(:param_one, :param_two).should eq(:result_one) + o.foo(:param_three, :param_four).should eq(:result_two) + end + end + end + """ + When I run `rspec example_spec.rb` Then the examples should all pass \ No newline at end of file diff --git a/lib/rspec/mocks/any_instance.rb b/lib/rspec/mocks/any_instance.rb index 1e294c14f..d8b81d5dc 100644 --- a/lib/rspec/mocks/any_instance.rb +++ b/lib/rspec/mocks/any_instance.rb @@ -11,10 +11,6 @@ def any_instance RSpec::Mocks::space.add(self) __recorder end - - def exactly_one_instance - any_instance - end def rspec_verify __recorder.verify diff --git a/lib/rspec/mocks/any_instance/message_chains.rb b/lib/rspec/mocks/any_instance/message_chains.rb index 91b85e0ca..18efeb42d 100644 --- a/lib/rspec/mocks/any_instance/message_chains.rb +++ b/lib/rspec/mocks/any_instance/message_chains.rb @@ -5,7 +5,7 @@ class MessageChains < Hash def add(method_name, chain) (self[method_name] ||= []) << chain end - + def has_expectation?(method_name) !!self[method_name].find{|chain| chain.is_a?(ExpectationChain)} end diff --git a/lib/rspec/mocks/any_instance/recorder.rb b/lib/rspec/mocks/any_instance/recorder.rb index a156ecba3..9176ef68e 100644 --- a/lib/rspec/mocks/any_instance/recorder.rb +++ b/lib/rspec/mocks/any_instance/recorder.rb @@ -2,6 +2,7 @@ module RSpec module Mocks module AnyInstance class Recorder + attr_reader :message_chains def initialize(klass) @message_chains = MessageChains.new @observed_methods = [] @@ -9,15 +10,22 @@ def initialize(klass) @klass = klass @expectation_set = false end - - def message_chains - @message_chains - end - def stub(method_name, *args, &block) - observe!(method_name) - message_chains.add(method_name, chain = StubChain.new(method_name, *args, &block)) - chain + def stub(method_name_or_method_map, *args, &block) + if method_name_or_method_map.is_a?(Hash) + method_map = method_name_or_method_map + method_map.each do |method_name, return_value| + observe!(method_name) + message_chains.add(method_name, chain = StubChain.new(method_name)) + chain.and_return(return_value) + end + method_map + else + method_name = method_name_or_method_map + observe!(method_name) + message_chains.add(method_name, chain = StubChain.new(method_name, *args, &block)) + chain + end end def should_receive(method_name, *args, &block) diff --git a/spec/rspec/mocks/any_instance_spec.rb b/spec/rspec/mocks/any_instance_spec.rb index eac070aca..092dda27e 100644 --- a/spec/rspec/mocks/any_instance_spec.rb +++ b/spec/rspec/mocks/any_instance_spec.rb @@ -1,3 +1,4 @@ + require 'spec_helper' module RSpec @@ -55,7 +56,21 @@ def another_existing_method; end klass.any_instance.stub(:foo) lambda{ klass.new.bar }.should raise_error(NoMethodError) end - + + context 'multiple methods' do + it "allows multiple methods to be stubbed in a single invocation" do + klass.any_instance.stub(:foo => 'foo', :bar => 'bar') + instance = klass.new + instance.foo.should eq('foo') + instance.bar.should eq('bar') + end + + it "adheres to the contract of multiple method stubbing withou any instance" do + Object.new.stub(:foo => 'foo', :bar => 'bar').should eq(:foo => 'foo', :bar => 'bar') + klass.any_instance.stub(:foo => 'foo', :bar => 'bar').should eq(:foo => 'foo', :bar => 'bar') + end + end + context "behaves as 'every instance'" do it "stubs every instance in the spec" do klass.any_instance.stub(:foo).and_return(result = Object.new)