I’m trying to spec a view but haven’t done much view specing.
This view render different partials depending on authentication of the
user:
annon, admin, player
So I I’ll write if conditionals in the view with the partials
it “should render signup propaganda for annon users trying to view
games”
do
render “/games/index.rhtml” @logged_in?.should eql(false)
response.should render_template(’_signup_propaganda’)
end
Now for my partial I know it’ll be wrapped all in a div with a
class=“signup_propaganda”
Should I be testing for that instead? Can I write expectations for
partials
similar to above?
When your specing views are you testing for the outputted results?
it “should render signup propaganda for annon users trying to view
games”
do
render “/games/index.rhtml” @logged_in?.should eql(false)
response.should have_tag(div, “class=/“signup_propaganda/””)
end
it “should render signup propaganda for annon users trying to view games”
do
render “/games/index.rhtml” @logged_in?.should eql(false)
response.should have_tag(div, “class=/“signup_propaganda/””)
end
How should I be writing my spec?
There is no simple answer to your question. If anyone offers you one,
treat it with a grain of salt.
Coding by example is a process. If you’re doing it right, the examples
are going to change as you progress. So in this case, I might start
like this:
it “should render signup propaganda for annon users trying to view
games” do
controller.stub!(:logged_in?).and_return(false)
render “/games/index.rhtml”
response.should have_tag(‘div.signup_propaganda’)
end
The code to make this pass could just be:
At this point I’d want to add an example about what a logged in user
sees to force the conditional:
it “should NOT render signup propaganda for logged in users trying to
view games” do
controller.stub!(:logged_in?).and_return(true)
render “/games/index.rhtml”
response.should_not have_tag(‘div.signup_propaganda’)
end
leading to this code:
<% if logged_in? %>
<% end %>
At some point down the line I might decide to extract the div to a
partial. At that point, I should be able to do so without changing
the example. Once the partial has been extracted, then comes the
question about what to do with the example, and the answer will depend
on a few things.
If the partial is only ever used in this one template, and requires no
additional setup, and the only reason I extracted it was to clean up
the template, I might leave things as/is.
Most of the time, however, I’d change the examples to expect that the
partial gets rendered. First, I’d create a new example for the partial
itself and move anything from the old example that was specific to the
content inside that partial. Only after that’s done and all examples
are passing, I’d change the original examples to look like this:
it “should render signup propaganda for annon users trying to view
games” do
controller.stub!(:logged_in?).and_return(false)
template.expect_render(:partial => ‘signup_propoganda’)
render “/games/index.rhtml”
end
it “should NOT render signup propaganda for logged in users trying to
view games” do
controller.stub!(:logged_in?).and_return(true)
template.expect_render(:partial => ‘signup_propoganda’).never
render “/games/index.rhtml”
end
ActionView::TemplateError in ‘/games/index.rhtml should render a list of
games for authenticated users’
undefined local variable or method `new_games_path’ for
#<#Class:0x32bd2a4:0x32bb5bc>
I am I suppose to stub the named route somehow?
since a link_to generates an anchor tag shouldn’t of my spec have passed?
What version of rspec/rspec_on_rails are you using?
it “should have a create games link for admin” do
template.stub!(:logged_in?).and_return(true)
template.stub!(:admin?).and_return(true)
template.should have_tag(‘a’,‘Create new game’)
render “/games/index.rhtml”
end
It says that it didn’t show up
‘/games/index.rhtml should have a create games link for admin’ FAILED
Expected at least 1 elements, found 0.
is not true.
./spec/views/games/index.rhtml_spec.rb:70:
Also all specs have a problem with the named route
ActionView::TemplateError in ‘/games/index.rhtml should render a list of
games for authenticated users’
undefined local variable or method `new_games_path’ for
#<#Class:0x32bd2a4:0x32bb5bc>
I am I suppose to stub the named route somehow?
since a link_to generates an anchor tag shouldn’t of my spec have
passed?
That’s not been released, so you must be working from trunk. I don’t
template.should have_tag(‘a’,‘Create new game’)
./spec/views/games/index.rhtml_spec.rb:70:
It didn’t know what controller was, should it not know it what
view.
specing.
it "should render signup propaganda for annon users
outputted
response.should have_tag(div,
Coding by example is a process. If you’re doing it right,
games" do
logged in
response.should_not have_tag(‘div.signup_propaganda’ )
a
If the partial is only ever used in this one template, and
the
are passing, I’d change the original examples to look like
The two problems were that I named my paths wrong and I was calling
template
instead of repsonse
it “should have a create games link for admin” do
template.stub!(:logged_in?).and_return(true)
template.stub!(:admin?).and_return(true)
render “/games/index.rhtml”
response.should have_tag(‘a’,‘Create new game’)
end
I’m stlll getting used to the whole spec’ing view things.
Its good to know my only problem is minor typo’s
it “should show a propaganda image” do
render “/games/index.rhtml”
response.should have_tag(‘img’,‘signup_propaganda.gif’)
end
The following doesn’t work. Im guess have_tag isnt the best approach to
test
them.
Should I just use have_text and look for the img and
signup_propaganda.gif?
Leaders are made, they are not born. They are made by hard effort,
which is the price which all of us must pay to achieve any goal that
is worthwhile.
Vince Lombardi
it “should show a propaganda image” do
render “/games/index.rhtml”
response.should have_tag(‘img’,‘signup_propaganda.gif’)
end
The following doesn’t work. Im guess have_tag isnt the best approach to test
them.
Should I just use have_text and look for the img and signup_propaganda.gif?
have_tag wraps assert_select, which is part of the rails testing API.
You can find docs on it here: