views:

31

answers:

2

Hi,

I'm starting to learn Rails. I'm using Rails 3.

In my simple App, I have the following code:

<% @tasks.each do |task| %>
  ...
    <td><%= friendly_estimate task.estimate, { :compact => true } %></td>
  ...
<% end %>

The mission for me is that I would like to test if the view really sends the :compact option to my method to ensure that the estimate is shown currently.

So the spec kinda is:

Estimates must be shown in compact view, on lists pages

I'm new to testing in Ruby, and totally new to View testing, so I hope someone can help out, or point me in the right direction.

Thanks :)

+2  A: 

Although you can test for the use of the compact option being sent to the friendly_estimate helper method using a variety of techniques, the primary purpose of a functional test is not to verify the implementation, but the output.

If you examine the output you should be able to determine if the proper formatting was used. The easiest way to do this is to insert some kind of CSS class that can be identified in the functional test. For instance, wrap your compact format in <span class="compact"> and then test for it using a CSS selector using assert_select:

assert_select 'td span.compact'

The functional tests should be ignorant of the implementation details to avoid binding them too strongly. This way you can refactor your models and helpers at will, yet still verify they are producing the correct output.

tadman
But the output can be different compared to alot of factors (language etc.) so is the practice just to call the function in the test like I want it to be called, and ensure that the same result is present in the output, using the selector?
Jesper Blad Jensen aka. Deldy
I'm sure the output can be radically different in terms of content, but the HTML DOM should be pretty much the same, or at least the important structural parts should be. If you want a particular kind of element to show up, test for the element, not the thing that's supposed to put it there. You need to verify that the option is working as designed, not that the option is being set.
tadman
This is why it's better to test for things like the presence of CSS elements with class `.account_failure.not_verified` than the presence of the text "Your account has not been verified". You need to think of how you can test things independent of language when you structure your HTML documents.
tadman
+1  A: 

I am using rspec, and using that it is actually very easy.

The way i would test it is

  • make sure the helper method is tested for the correct output in all possible cases.

  • make sure in your view you test that the helper is called. From your earlier tests you will know that the output will be correct. Your view is tested in total isolation, so you create mock objects that will return fixed results, and you test if the helpers are called.

So how do you do that?

In rspec you can just mock the helper method, like this:

template.should_receive(:friendly_estimate)

you could even specify which parameters it should receive:

task = mock(Task)
task.should_receive(:estimate).and_return(SOME_ESTIMATE)
template.should_receive(:friendly_estimate).with(SOME_ESTIMATE, :compact => true)

this will give an error if those expectations are not met.

More info here.

nathanvda