Writing a spec for helper with Ruby on Rails and RSpec
Solution 1
RSpec should automatically load classes and modules from your rails environment when you 'describe' them, so a valid helper spec could be:
#deleted
But remember that bdd is not testing every single method but the behaviour of your application.
edit:
as @Ken said, my spec was not correct, It was definately the wrong way to do it. So I came out with a Request spec solution that I like more than an Helper spec.
# inside your helper
def title=(page_title)
content_for(:title) { page_title }
end
# views/resource/index.html.erb
<% title = "foo" %>
# views/layouts/application.html.erb
<%= yield :title %>
# request spec
require 'spec_helper'
describe YourResource do
it "should output content for title"
get "/resource"
response.body.should =~ /<title>foo<\/title>/
end
end
otherwise, if you want to test only the helper behavior (because it's critical or because you don't have any views) @Ken's solution is better.
Solution 2
From the rspec-rails docs on Helper Specs:
Helper specs live in spec/helpers, and mix in ActionView::TestCase::Behavior.
Provides a helper object which mixes in the helper module being spec'd, along with ApplicationHelper (if present).
require 'spec_helper'
describe ApplicationHelper do
describe "#title" do
it "displays the title" do
# helper is an instance of ActionView::Base configured with the
# ApplicationHelper and all of Rails' built-in helpers
expect(helper.title).to match /Some Title/
end
end
end
Solution 3
It is possible to use this syntax when spec'ing helpers
Suppose this is your helper
module ApplicationHelper
def page_title
@title || nil
end
end
Then you can spec it with this syntax
require "spec_helper"
describe ApplicationHelper do
describe "#page_title" do
it "returns the instance variable" do
assign(:title, "My Title")
helper.page_title.should eql("My Title")
end
end
end
Solution 4
It is also possible to include your helper inside the test class as follows:
describe ApplicationHelper do
helper ApplicationHelper
it "should work" do
my_helper_method("xyz").should == "result for xyz"
end
end
Worked for me with Rails 3.
Solution 5
Parsing html with regular expressions is really reinventing the wheel. That's way too much work for me: too inflexible, and too error prone. (See this sarcastic but hilarious and accurate SO answer about the reasoning)
If you need to parse the html output by your helpers, you might try the gem rspec-html-matchers. Unlike webrat, it seems to play well with RSpec 3.
Then you can:
expect(helper.title).to have_tag('title', text: 'What you expect')
Related videos on Youtube
Comments
-
TK. almost 4 years
I have been writing specs for controllers and models, but I have never written a helper spec. I have no idea where I start.
I have the following snippet in
application_helper.rb
def title(page_title) content_for(:title) { page_title } end
- How should I write a helper spec on the code?
- Also if there's any open-source Rails app to show good helper testing/specing, do let me know.
-
TK. over 14 yearsThanks so much for your example. Right BDD is not about covering every method. Most helper methods are touched by Cucumber/Rcov coverage.
-
Ken Mayer about 14 yearsThis doesn't test much since content_for returns nil. You should render a page and assert_select "title" contains what you expect.
-
Percy about 11 yearsThis isn't testing a helper, this is testing something else, based on your example it looks like it's testing a view file (e.g. index.html.erb). The helper test should just test the ApplicationHelper#title method itself, without any dependencies on a view or a route/controller.
-
makevoid about 11 yearsI usually don't test simple view helpers, I prefer request specs because they test behaviour over a single functionality. @KenMayer, I've corrected the code.