Showing posts with label rspec. Show all posts
Showing posts with label rspec. Show all posts

July 26, 2007

Run your JRuby RSpec tests from Maven

On my most recent project we made heavy use of RSpec. After 6+ months of using it I must admit that I am a big fan. Therefor I was very happy to see that JRuby included RSpec within its distro (see JRuby bundles RSpec).

I have also been working on adding JRuby support for Waffle. So I decided to write my Ruby tests for Waffle with RSpec. Additionally, I wanted these RSpec tests to run as part of the build. Waffle, like many Java open source projects, uses Maven 2. Regardless of whether you love or hate Maven its dependency and repository convention have became a standard way to easily distribute jars. So I wrote an Maven plug-in that allows you to execute your RSpec tests from Maven. We have since contributed this to Codehaus' Mojo Project. So give it a look if you have the need.



** Ruby support within Waffle will allow developers to write their Controllers, and other objects, with straight Ruby syntax. Look for more info on this functionality soon.

March 20, 2007

RSpec:Rails - How to mock partials when testing a View.

When developing Ruby on Rails (RoR) applications I prefer to use RSpec over the built in testing framework provided with RoR. The biggest benefit is that RSpec easily allows you to test your application layers in isolation (e.g. when testing a Controller you should not be interested in testing the Model). So with that in mind when I am testing a View I am only interested in testing that View and not any of the potential partials that View may try to render.

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.