且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

测试无法直接访问的RSpec控制器操作

更新时间:2023-12-01 15:39:22

控制器测试使用四个HTTP动词(GET,POST,PUT,DELETE),而不管您的控制器是否为RESTful。因此,如果您有非RESTful路由(Rails3)

  match'example'=&gt ; 'story#example'

这两个测试:


$ b b
  require'spec_helper'

describe StoryController do

描述GET'example'do
it应该成功do
get:example
response.should be_success
end
end

描述POST'example'do
它应该成功do
post:example
response.should be_success
end
end

end
$ c $

EDIT



我想你正在混淆控制器测试和路由测试。在控制器测试中,您要检查该操作的逻辑是否正确工作。在路由测试中,您可以检查URL是否到达正确的控制器/操作,以及params哈希是否正确生成。



因此,要测试您的控制器操作, :

  post:create,:provider => twitter`

要测试路由,请使用 params_from (对于Rspec 1)或 route_to (对于Rspec 2):

  describeroutingdo 
itroutes / auth /:provider / callbackdo
{:post => / auth / twitter / callback} .should route_to(
:controller =>authentications,
:action =>create,
:provider =>twitter )
end
end


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

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