Navigation Menu

Skip to content

Commit

Permalink
Fixed broken feature related to multiple method stubs and added anoth…
Browse files Browse the repository at this point in the history
…er for any_instance.stub.with - this should close Issue rspec#58
  • Loading branch information
kaiwren committed Jun 17, 2011
1 parent 3c129ae commit e542b18
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 14 deletions.
19 changes: 19 additions & 0 deletions features/method_stubs/any_instance.feature
Expand Up @@ -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
4 changes: 0 additions & 4 deletions lib/rspec/mocks/any_instance.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/rspec/mocks/any_instance/message_chains.rb
Expand Up @@ -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
Expand Down
24 changes: 16 additions & 8 deletions lib/rspec/mocks/any_instance/recorder.rb
Expand Up @@ -2,22 +2,30 @@ module RSpec
module Mocks
module AnyInstance
class Recorder
attr_reader :message_chains
def initialize(klass)
@message_chains = MessageChains.new
@observed_methods = []
@played_methods = {}
@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)
Expand Down
17 changes: 16 additions & 1 deletion spec/rspec/mocks/any_instance_spec.rb
@@ -1,3 +1,4 @@

require 'spec_helper'

module RSpec
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit e542b18

Please sign in to comment.