method

stub_chain

Importance_3
stub_chain(*methods) public

No documentation

This method has no description. You can help the RSpec community by adding new notes.

Show source
Register or log in to add new notes.
March 4, 2010 - (>= 1.2.8)
5 thanks

stub_chain is very useful when testing controller code

or any other chained method call type that you’d like to stub, example:

in your controller:

def new
  @user = current_site.users.new
end

in your spec:

it "#new should assign a @user" do 
  u = mock("User")
  controller.stub_chain(:current_site, :users, :new).and_return(u)
  assigns[:user].should == u
end

whereas before you had to stub each chained method call separately:

it "#new should assign a @user" do 
  u = mock("User")
  users = mock("Users collection", :new => u)
  site = mock("Site", :users => users)
  controller.stub!(:current_site).and_return(site)
  assigns[:user].should == u
end

Please note that stub_chain was added to RSpec in version 1.2.6

July 21, 2010
2 thanks

Works only inside the "it" block

Please note that stub_chain doesn’t work outside of the it...do...end block.

If you need to create more complicated chains using a function you need to use the old way.

July 12, 2013 - (1.1.4 - 1.3.1)
1 thank

correct, but ..

stub_chain provides a very good replacement of long lines of nested stubs, but never forget it violates Law of Demeter; i.e. it indicates an increase of coupling in your classes and this is a bad thing because it means your objects now are making more unnecessary calls to other objects. for example:

def initialize(some_obj)
  @obj = some_obj
end

def foo
  @obj.x  # GOOD coupling - according to LoD you are allowed to call a method on your object
end

def bar
  @obj.x.y   # BAD coupling - can not call a method on a returned value of another method call even if the initial call is legal
end

How is this related to TDD and stubs?

  • method foo test will have only one stub for a double of some_obj type

  • method bar will have 2 stubs: the first is going to swallow the other one to produce the result (and then can be shortened using this stub_chain technique)

Always remember: if your tests are using stub_chains –> your code is smelly and possibly tightly coupled.