Suppose we have the View /example/hello_world.rhtml:
<div id="person">
<h2 class="title">Hello <%= @person.name %></h2>
<%= render :partial => 'address', :locals => {:person => @person} %>
</div>
Often in RSpec when testing a view such as this the spec ends up testing the partial as well. This is less than desirable because any change to the partial could break test for other views that render that partial. After some investigation I discovered that I could mock the calls to <%= render :partial => 'address'... %>. Have a look at the following spec:
specify 'should call mock and not the actual partial' do
person = mock('person')
person.should_receive(:name).and_return('Regan')
assigns[:person] = person
# Mock the call to 'render_partial'...
@controller.template.should_receive(:render).with(:partial => 'address', :locals => {:person => person})
render '/example/hello_world'
response.should_have_tag(:h2, :content => "Hello Regan")
end
You can grab a handle to the ActionView through @controller.template as is done in the example above. Then I mock the call to the 'render' method only when the 'address' partial is requested.
As you can see my spec only needs to be concerned with testing the /example/hello_world.rhtml View. The partial will have it's own separate spec. The side effect is that my view specification becomes much more manageable and far less brittle.