RSpec’s mocking/stubbing facilities are enhanced significantly in RSpec-0.7.

<p>You can now intermingle stub methods and mock expectations on the same objects. This applies to instances of Spec::Mocks::Mock or <span class="caps">ANY</span> other object or class.</p>


<p>Having integrated stubs and mocks available not only supports isolated and fast controller specs, it also provides a nice way to separate setup noise from the &#8220;interesting bits&#8221; in your specs. I try to exploit this by preferring stub methods (stub!) in my setup and mock expectations (should_receive) in specify blocks.</p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

context "the PersonController" do
  controller_name :person
  
  setup do
    @person = mock("person")
    Person.stub!(:new).and_return(@person)
  end
  
  specify "should create a new person on GET to create" do
    Person.should_receive(:new).and_return(@person)
    get 'create'
  end
  
  specify "should assign new person to template on GET to create" do
    get 'create'
    assigns[:person].should_be @person
  end
  
  specify "should render 'person/create' on GET to create" do
    controller.should_render :template => "person/create"
    get 'create'
  end
  
end
<p>In this example, the line &#8230;</p>


Person.stub!(:new).and_return(@person)

… in setup stubs the method so GET ‘create’ will work every time. The line …


Person.should_receive(:new).and_return(@person)

… in the specify block “should create a new person on GET to create” sets an expectation that must be met. Even though it seems like duplication of the stub method, it is serving a different function: it tells the story for that spec.

<p>Note how in the other specs there is no focus on Person.new. It&#8217;s out of the way, but the stub in the setup makes sure its taken care of.</p>


<p>So use stubs to take care of the &#8220;noise&#8221; (in this case stuff that has to be there to get the specs to run), and use mock expectations to put focus on the fact that something is expected.</p>

Comments are closed.