Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Given I set up a HomeController with an index action

class HomeController < ApplicationController
  def index
    @users = User.all
  end
end

and routed to it via the root path,

  root :to => "home#index"

why does this request spec fail

it 'should called the home#index action' do
    HomeController.should_receive(:index)
    visit root_path
end

with the following message

 Failure/Error: HomeController.should_receive(:index)
   (<HomeController (class)>).index(any args)
       expected: 1 time
       received: 0 times

? Is it because the index method is called as a instance method instead of a class method?

share|improve this question
1  
Assuming that spec is under your spec/controllers directory, try just changing the line to controller.should_receive(:index) and see if that works. –  Paul Fioravanti Jun 8 at 23:44
 
The spec resides in spec/request and I prefer that it be a request spec. And no, it does not work in spec/controllers/home_controller_spec.rb even after the change: controller.should_receive(:index) (#<HomeController:0x00000004989e10>).index(any args) expected: 1 time received: 0 times –  user2191332 Jun 9 at 3:30
add comment

1 Answer

up vote 5 down vote accepted

I'm not sure exactly what you want to test, and I think there's some confusion as to what methods can be used where, so I'll try and give examples of Routing specs, Request Specs, Controller specs, and Feature specs, and hopefully one of them will be appropriate for you.

Routing

If you want to make sure that your root path gets routed to the home#index action, a routing spec may be appropriate:

spec/routing/routing_spec.rb

describe "Routing" do
  it "routes / to home#index" do
    expect(get("/")).to route_to("home#index")
  end
end

Request

If you want to make sure that the index template gets rendered on a request to your root path, a request spec may be appropriate:

spec/requests/home_requests_spec.rb

describe "Home requests" do
  it 'successfully renders the index template on GET /' do
    get "/"
    expect(response).to be_successful
    expect(response).to render_template(:index)
  end
end

Controller

If you want to make sure that the index template gets rendered on a request to the index action of your HomeController, a controller spec may be appropriate (and quite similar to a request spec in this case, but focused exclusively on the controller):

spec/controllers/home_controller_spec.rb

describe HomeController do
  describe "GET index" do
    it "successfully renders the index template" do
      expect(controller).to receive(:index) # this line probably of dubious value
      get :index
      expect(response).to be_successful
      expect(response).to render_template(:index)
    end
  end
end

Feature

If you want to make sure the page rendered by home#index has some specific content, a feature spec may be appropriate (and also the only place you can use Capybara methods like visit, depending on your Rails/RSpec version):

spec/features/home_features_spec.rb

feature "Index page" do
  scenario "viewing the index page" do
    visit root_path
    expect(page).to have_text("Welcome to my awesome index page!")
  end
end
share|improve this answer
 
I see. So #should_receive works with #get but not #visit and must use the controller instance in HomeController. What I actually want to test is signing in through omniauth, which is why I want integration tests. The only thing I care about is that Sessions#create is called, and not where it is routed as I will redirect the user back to where he came from. It seems that the best thing is just to test the behavior in the Sessions#create method. Is that the most appropriate? –  user2191332 Jun 9 at 17:11
 
There's lots of similar questions about writing specs for Omniauth on StackOverflow and guides at Railscasts among others. Have a look through those resources and see what is right for you. –  Paul Fioravanti Jun 9 at 23:26
1  
@user2191332 You should accept Paul Fioravanti's answer, It is a great one –  Andreas Lyngstad Jun 10 at 21:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.