I'm testing access to a page with a bunch of different types of users. I'm tyring to see which page is rendered for each type. I can't find the right syntax to do so. I'm also not sure if this should be in a views file rather than controller.
describe "GET show as admin" do
before(:each) do
session[:admin_user_id] = FactoryGirl.create(:admin_user).id
end
it "is available to view by admin" do
data_service = FactoryGirl.create(:published_data_service)
get :show, {:id => data_service.to_param}
assigns(:data_service).should eq(data_service)
response.should render_template('show')
end
end
render_template is returning as [].
Other note: Capybara is included in the Gemfile, and is being required in spec_helper
Related
Working on controller testing and wanted to test that when I go to the index page, I should see the total number of users created and that should equal all the users that were in fact created. Can't get it to work and no errors are coming up, it just freezes and I have to press control c to exit.
describe "GET #index" do
it "show a list of all users" do
total = User.all.count
get :index
expect(response).to eq total
end
rspec controller tests don't render views by default, testing success might be better start
describe "GET #index" do
it "show a list of all users" do
get :index
expect(response).to be_success
end
end
If you really want to check rendering
describe "GET #index" do
render_views
it "show a list of all users" do
total = User.all.count
get :index
expect(response).to contain total.to_s
# OR
expect(response.body).to match total.to_s
end
end
see: https://www.relishapp.com/rspec/rspec-rails/v/2-2/docs/controller-specs/render-views
If you want check displaying of some information on page, it will be better to write integrations test using Capybara.
Purpose of controller tests is to check incoming parameters, variables initialized in controller and controller response (rendering views or redirecting...).
About your question - if you have next controller:
class UsersController < ApplicationController
def index
#users = User.all
end
end
you can write next controller test:
describe UsersController do
it "GET #index show a list of all users" do
User.create(email: 'aaa#gmail.com', name: 'Tim')
User.create(email: 'bbb#gmail.com', name: 'Tom')
get :index
expect(assigns[:users].size).to eq 2
end
end
I have a rails 3.2.13 app running rspec-rails 2.14.0 and am trying to confirm that a view renders a particular partial in my test. It actually does work, but I need to add this test. Here's what I have so far:
require 'spec_helper'
describe 'users/items/index.html.haml' do
let(:current_user) { mock_model(User) }
context 'when there are no items for this user' do
items = nil
it 'should render empty inventory partial' do
response.should render_template(:partial => "_empty_inventory")
end
end
end
This runs without error, but does not pass. The failure is:
Failure/Error: response.should render_template(:partial => "_empty_inventory")
expecting partial <"_empty_inventory"> but action rendered <[]>
Thanks for any ideas.
EDIT
This works for me, but Peter's solution is better...
context 'when there are no items for this user' do
before do
view.stub(current_user: current_user)
items = nil
render
end
it 'should render empty inventory partial' do
view.should render_template(:partial => "_empty_inventory")
end
end
For some reason it was counter-intuitive to me to have to call render on a view, but there you go...
So the way one usually tests whether a particular partial is rendered in a view spec is by testing the actual content of the partial. For example, assume that your _empty_inventory parial has the message 'There is no inventory'. Then you might have a spec like:
it "displays the empty inventory message" do
render
rendered.should_not have_content('There is no inventory')
end
Alternately, you could use a controller spec, in which case you need to call the 'render_views' method when setting up the spec. Then you can do something similar to
it 'should render empty inventory partial' do
get :index, :user_id => user.id
response.should render_template(:partial => "_empty_inventory")
end
Assuming you've set up the state for the contoller spec.
I am trying to check the title of a page, but it is failing with:
rspec ./spec/controllers/pages_controller_spec.rb:13 # PagesController GET 'home' should have the right title
Here is what pages_controller_spec.erb looks like:
render_views
describe "GET 'home'" do
it "returns http success" do
get 'home'
response.should be_success
end
it "should have the right title" do
get 'home'
response.should have_selector("title",:content => "Home")
end
end
According to this, I think you need :text not :content:
http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders#all-instance_method
I hope that helps.
rspec controller tests stub the view so you can test the controller in isolation
https://www.relishapp.com/rspec/rspec-rails/v/2-12-2/docs/controller-specs/views-are-stubbed-by-default
if you check the response object it probably contains a blank string
the idea being you should test
if the correct template rendered
if the controller redirected correctly
if the controller called the correct models, etc...
that being said, if you want the test to render the view, use render_views in the describe block
https://www.relishapp.com/rspec/rspec-rails/v/2-2/docs/controller-specs/render-views
Building off of what house9 says, you should test the title of your views somewhere else, and not in your controller specs. For instance, you can create a "requests" directory within your spec directory and test page features there. For more information on request specs:
http://railscasts.com/episodes/257-request-specs-and-capybara?view=asciicast
I have 2 simple RSpec tests i've written for a small rails app i've done to learn rails. I originally had a mock setup for my Link class but was getting the same issue.
This is my test code:
require 'spec_helper'
describe LinksController do
render_views
before(:each) do
link = Link.new
link.stub!(:title).and_return("Reddit")
link.stub!(:url).and_return("http://www.reddit.com")
link.stub!(:created_at).and_return(Time.now)
link.stub!(:updated_at).and_return(Time.now)
link.stub!(:user_id).and_return("1")
link.stub!(:id).and_return("1")
link.save
user = User.new
user.save
end
it "renders the index view" do
get :index
response.should render_template('links/index')
response.should render_template('shared/_nav')
response.should render_template('layouts/application')
end
it "renders the show view" do
get :show, :id => 1
response.should render_template('links/show')
response.should render_template('shared/_nav')
response.should render_template('layouts/application')
end
end
I'm new to both rails and RSpec, not sure what I should be doing to get this to work. What is the best way to test this show method from my LinksController when you need data? I tried mock_model too but maybe I was using it wrong.
You can see all the app code on Github
The problem is that you are stubbing a model, so it's not stored in the database. That means that when you call get :show, :id => 1 the query to the database returns nothing and your tests fail. Stubbing is great when you want to fake a response or an object without using the database, but if you are depending on actual Rails code that uses the database you can't use this method because nothing exists in the database. To fix this I would drop the stubbed models entirely and actually create them.
require 'spec_helper'
describe LinksController do
render_views
before(:each) do
user = User.create
#link = Link.create :title => "Reddit",
:url => "http://www.reddit.com",
:user => user
end
it "renders the index view" do
get :index
response.should render_template('links/index')
response.should render_template('shared/_nav')
response.should render_template('layouts/application')
end
it "renders the show view" do
get :show, :id => #link.id
response.should render_template('links/show')
response.should render_template('shared/_nav')
response.should render_template('layouts/application')
end
end
You should also eventually look into Factory gems like Sham and Factory Girl to simplify the creation of test data.
i am working in Rspec of ROR..
I am trying to test my controllers using RSpec.i am having a Users controller with functions like new , tags, etc..
i created a file under spec/users_controller_spec.rb
and added the test cases as.
require 'spec_helper'
describe UsersController do
integrate_views
it "should use UsersController" do
controller.should be_an_instance_of(UsersController)
end
describe "GET 'new'" do
it "should be successful" do
get 'new'
response.should be_success
end
it "should have the title" do
get 'new'
response.should have_tag("title", "First app" )
end
end
end
which gets pass.
But when i add a test case for tags ..
like
describe "GET 'tags'" do
it "should be successful" do
get 'tags'
response.should be_success
end
end
this results in an error as
F...
1)
'UsersController GET 'tags' should be successful' FAILED
expected success? to return true, got false
why it is coming like this ?? i am very new to ROR and cant find the reason of why i am getting this error..
How to make this pass .
Also i tried the Url
http://localhost:3000/users/tags which is running for me .. But on testing using $spec spec/ i am getting the error ..
Your test may be failing for any number of reasons. Does the route require an ID in the parameter hash? Is the controller action redirecting? Is the controller raising an error?
You'll need to look at the controller code /and/or routes.rb to discover the cause of the failure. Take note of before filters in the controller, which may not allow the action to be reachable at all.
You need to add custom routes that are not within the default 7 routes. Assuming you have resources :users within your routes you will need to modify it. I'm also assuming that your tags route is unique to individual users.
resources :users do
member do
# creates /users/:user_id/tags
get :tags
end
end
And in your RSpec test you would call it like
describe '#tags' do
user = create :user
get :tags, user_id: user.id
end
If the route is not to be unique per user the other option is a collection route, something like:
resources :users do
collection do
# creates /users/tags
get :tags
end
end