Testing an RSpec controller action that can't be accessed directly

浪子不回头ぞ 提交于 2019-12-31 01:58:48

问题


I've got a controller that can't be accessed directly, in the traditional RESTful way, but rather only through a particular url.

Normally I'm used to using get and post in my controller specs to call controller actions. Is there a way that I can exercise my controller by visiting a particular url?

EDIT:

Here is my route:

Larzworld::Application.routes.draw do

  match '/auth/:provider/callback' => 'authentications#create'

  devise_for :users, :controllers => {:registrations => "registrations"} 

  root :to => 'pages#home'
end

Here is my spec:

require 'spec_helper'

describe AuthenticationsController do

before(:each) do
  request.env["omniauth.auth"] = {"provider" => "twitter", "uid" => "12345678"} 
end

describe 'POST create' do

  it "should find the Authentication using the uid and provider from omniauth" do
    Authentication.should_receive(:find_by_provider_and_uid)
    post 'auth/twitter/callback'
  end
end

end

and here is the error I receive:

Failures:
  1) AuthenticationsController POST create should find the Authentication using the uid and provider from omniauth
    Failure/Error: post 'auth/twitter/callback'
    No route matches {:action=>"auth/twitter/callback", :controller=>"authentications"}
    # ./spec/controllers/authentications_controller_spec.rb:13

Finished in 0.04878 seconds
1 example, 1 failure

回答1:


Controller tests use the four HTTP verbs (GET, POST, PUT, DELETE), regardless of whether your controller is RESTful. So if you have a non-RESTful route (Rails3):

match 'example' => 'story#example'

the these two tests:

require 'spec_helper'

describe StoryController do

  describe "GET 'example'" do
    it "should be successful" do
      get :example
      response.should be_success
    end
  end

  describe "POST 'example'" do
    it "should be successful" do
      post :example
      response.should be_success
    end
  end

end

will both pass, since the route accepts any verb.

EDIT

I think you're mixing up controller tests and route tests. In the controller test you want to check that the logic for the action works correctly. In the route test you check that the URL goes to the right controller/action, and that the params hash is generated correctly.

So to test your controller action, simply do:

post :create, :provider => "twitter"`

To test the route, use params_from (for Rspec 1) or route_to (for Rspec 2):

describe "routing" do
  it "routes /auth/:provider/callback" do
    { :post => "/auth/twitter/callback" }.should route_to(
      :controller => "authentications",
      :action => "create",
      :provider => "twitter")
  end
end


来源:https://stackoverflow.com/questions/4227638/testing-an-rspec-controller-action-that-cant-be-accessed-directly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!