Testing links using rspec? - ruby-on-rails

If I have something like <%= link_to "Help", help_path %> in the view file, how do I test the following using rspec?
It goes to help_path.
The content reads "Help".
I am currently using capybara.
edit
While answers below can work, I think I found a simpler way of doing this.
describe "some link on whatever page" do
subject { page }
before { visit whatever_path }
it { should have_link('Help', href: help_path) }
end

If you are using capybara then
my_link = find(:css, "a:contains('Help')")
my_link.click
and get page status, should be 200 or simply check
my_link.href
But also you could simply add routes specs to your integration specs in rspec. Like this to be always sure this routes exists
describe HelpController do
it "should have proper routes" do
{:get => "/halp/772/parser/18/edit" }.should be_routable
{:post => "/halp/772/parser" }.should be_routable
{:delete => "/halp/772/parser/18" }.should be_routable
end
end

Your file could look like this:
require 'spec_helper'
feature "Help" do
scenario "creation" do
visit help_path # access your help path
page.should have_content("Help") # verify content
end
end
If you need some help with testing with Capybara you could find some here:
Railscasts #257 Request Specs and Capybara or
Capybara repo at Github

Use have_tag matcher. Here is a cheatsheet.
response.should have_tag("a[href$=#{help_path}]", :text => "Help")
P.S. Did you read rails guides?

click_link "Help"
Gist of a capybara cheatsheet: https://gist.github.com/zhengjia/428105

Related

have_selector is failing test

I am having a problem including a should have_selector problem with rspec:
This is my code:
describe "GET 'home'" do
it "returns http success" do
get 'home'
expect(response).to be_success
end
it "should have the right title" do
should have_selector("title",
:content => "Ruby on Rails Tutorial Sample App | Home")
end
end
I have included the following at the top:
RSpec.describe PagesController, :type => :controller do
render_views
My html5 has the following:
<title>Ruby on Rails Tutorial Sample App | Home</title>
and I get an error message saying:
Failures:
1) PagesController GET 'home' should have the right title
Failure/Error: should have_selector("title",
expected #<PagesController:0x007fceef586a90> to respond to `has_selector?`
# ./spec/controllers/pages_controller_spec.rb:14:in `block (3 levels) in <top (required)>
Can someone help with that?
rspec -v
3.0.2
rails 4.1.1
thank you in advance.
Rspec 3 does not include the capybara matchers in controller specs by default. You can change this for an individual spec by doing
include Capybara::RSpecMatchers
Or, in your spec helper
config.include Capybara::RSpecMatchers, :type => :controller
Your next issue is that recent versions of capybara don't allow you to test for the presence of invisible elements by default, and the title element is considered to be invisible. You should use the have_title matcher instead.
Hollo rubyist pal!
I had this problem and that was because of two things, first I did not use capybara gem, and second have_selector only accepts one of :count, :minimum, :maximum, :between, :text, :visible, :exact, :match, :wait keys and does not understand :content.
I am sure you solved the problem, but for those who have started to learn Ruby on Rails recently and encountered such a problem I should say to eleminate it first put capybara gem in your Gemfile as below:
group :development, :test do
...
gem 'capybara'
end
and run command
bundle install
then to test that your view has a specific title, in pages_controller_spec.rb file write
describe "GET #home" do
...
it "should have the right title" do
get :home
expect(response.body).to have_selector('title', :text => 'Ruby on Rails rocks')
end
end
I hope it would help someone.
Cheerio!
Checking content is view spec...
And controller spec means checking response status/path, render page/partials, instance variable filters params.

rails 3.2 capybara Capybara::ElementNotFound:Unable to find xpath "/html"

I am trying to test my rails app with rspec 2.10.0 + capybara 1.1.2. Here is my test file
require 'spec_helper'
describe AdminPanelController do
describe "index" do
it "should have return code 200" do
visit '/admin'
page.should have_content "hello"
#response.status.should be(200)
end
end
end
And here are test result
Failure/Error: page.should have_content "hello"
Capybara::ElementNotFound:
Unable to find xpath "/html"
I google about this issue but find only information that webrat can be a problem however i do not have this gem installed. Thanks for any suggestions.
Wrong type of test. This looks like a controller test, which does tests with methods like get and post and is in the spec/controllers folder. Request specs, which use capybara, reside in spec/requests. Run $ rails generate scaffold SomeModel to see how they each should look.
If you understood the above but would still like to use capybara for your controller test, modify your describe block:
describe AdminPanelController, :type => :request do
...
end

Why i can not get current_user while writing test case with Rspec and Capybara

I have to write integration test case for my one feature listing page and that feature index method has code like below
def index
#food_categories = current_user.food_categories
end
Now when i try to write a test case for this it throws an error
'undefined method features for nil class' because it can not get the current user
Now what i have do is below
I have write the login process in the before each statement and then write the test case for the features listing page
Can you please let me know that how i can get the current_user ?
FYI, I have used devise gem and working on integration test case with Rspec
Here is my spec file
And here is my food_categories_spec.rb
Update: you confuse functional and integration tests. Integration test doesn't use get, because there's no controller action to test, instead you must use visit (some url). Then you have to examine content of a page, not response code (latter is for functional tests). It may look like:
visit '/food_categories'
page.should have_content 'Eggs'
page.should have_content 'Fats and oils'
In case you'll need functional test, here's an example:
# spec/controllers/your_controller_spec.rb
describe YourController do
before do
#user = FactoryGirl.create(:user)
sign_in #user
end
describe "GET index" do
before do
get :index
end
it "is successful" do
response.should be_success
end
it "assings user features" do
assigns(:features).should == #user.features
end
end
end
# spec/spec_helper.rb
RSpec.configure do |config|
#...
config.include Devise::TestHelpers, :type => :controller
end

Can't get RSpec view spec to pass

I've got the following spec in spec/views/users/new.html.erb_spec.rb:
require 'spec_helper'
describe "users/new.html.erb" do
it "displays the text attribute of the message" do
render
response.should contain("Register")
end
end
But when I run the test it fails with:
ActionView::TemplateError in 'users/new.html.erb displays the text attribute of the message'
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
The line it is failing on is:
<% form_for #user, :url => account_path do |f| %>
In my Users controller for the new method, I have this:
#user = User.new
Any ideas why I'm getting that error?
UPDATE: Per request, here's my routes file...
ActionController::Routing::Routes.draw do |map|
map.resource :account, :controller => "users"
map.resources :users
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
The view specification is run in complete isolation from the Users controller. Thus, you have to initialize the variables needed in the view yourself, as described here. The result would be something like this:
require 'spec_helper'
require 'path/to/user.rb'
describe "users/new.html.erb" do
it "displays the text attribute of the message" do
assigns[:user] = User.new
render
response.should contain("Register")
end
end
If you want to test your view together with your controller, I would suggest looking into integration testing with Cucumber.
Just a more updated answer.
require 'spec_helper'
describe "users/new.html.erb" do
it "displays the text attribute of the message" do
assign(:user, stub_model(User))
render
expect(rendered).to include("Register")
end
end
This should work on rails 3.2.13 and rspec 2.13.0

How to use rspec to test named routes?

Given I have a named route:
map.some_route '/some_routes/:id', :controller => 'some', :action => 'other'
How do I use the routing spec file 'spec/routing/some_routing_spec.rb' to test for that named route?
I've tried this after the "describe SomeRouteController" block and it doesn't work, I get 'undefined method "helper":
describe SomeRouteHelper, 'some routes named routes' do
it 'should recognize some_route' do
helper.some_route_path(23).should == '/some_routes/23'
end
end
If this is in a controller spec, you can call the routing method directly, no helper needed.
describe SomeController do
it 'should recognize ma routes!' do
thing_path(23).should == '/things/23'
end
end
In RSpec-Rails 2.7+ you can create a spec/routing directory and put your routing specs in there. See the rspec-rails docs for more info.
there's a nice shoulda matcher for this too:
it { should route(:get, "/users/23").to(:action => "show", :id => 23)
more information on using shoulda matchers with rspec:
https://github.com/thoughtbot/shoulda-matchers
You can do this in your controller specs with the assert_routing method, like so:
describe UsersController do
it "should recognize a specific users#show route" do
assert_routing("/users/23", {:controller => "users", :action => "show", :id => 23})
end
end
More documentation is here.
This is how I write the specs using RSpec2, Shoulda, and Capybara. You would save this example file in #{Rails.root}/spec/routing/thingz_routing_spec.rb or my preference #{Rails.root}/spec/routing/thingz_controller_spec.rb
require "spec_helper"
describe ThingzController do
describe "routing" do
it "routes to #index" do
get("/thingz").should route_to("thingz#index")
end
end
end

Resources