2014-04-21 2 views
3

현재 API를 빌드하고 컨트롤러를 테스트하려고합니다. 내가 해결할 수없는 Devise와 관련된 오류가 발생합니다. 여기에 내가 현재 가지고있는 것입니다 :Rails 4 + Rails-API + RSpec + Devise - 사용자 정의 경로가있는 Trouble 테스팅 컨트롤러

# /spec/requests/api/v1/sessions_spec.rb 
require 'spec_helper' 

describe API::V1::SessionsController do 
    describe "POST /sessions" do 
    it "on success, returns the user's authentication token" do 
     user = FactoryGirl.create(:user) 

     user_params = { 
     "user" => { 
      "email" => user.email, 
      "password" => user.password 
     } 
     }.to_json 

     post "/api/v1/sessions", user_params 

     expect(response.status).to eq(200) 
     json = JSON.parse(response.body) 
     expect(json['authentication_token']).to eq(user.authentication_token) 
    end 
    end 
end 


# /app/controllers/api/v1/sessions_controller.rb 
class API::V1::SessionsController < Devise::SessionsController 
    respond_to :json 

    def create 
    end 
end 


# routes.rb 
MyApplication::Application.routes.draw do 
    namespace :api, defaults: { format: :json } do 
    namespace :v1 do 
     devise_scope :user do 
     post 'sessions' => 'sessions#create', :as => 'login' 
     end 
    end 
    end 
end 

오류가 나는 점점 전류입니다 :이 문제를 해결하기 위해 주변 검색, 및 다른 질문에서 무리를 시도

1) API::V1::SessionsController POST /sessions on success, returns the user's authentication token 
Failure/Error: post "/api/v1/sessions", user_params 
AbstractController::ActionNotFound: 
    Could not find devise mapping for path "/api/v1/sessions". 
    This may happen for two reasons: 

    1) You forgot to wrap your route inside the scope block. For example: 

    devise_scope :user do 
     get "/some/route" => "some_devise_controller" 
    end 

    2) You are testing a Devise controller bypassing the router. 
     If so, you can explicitly tell Devise which mapping to use: 

     @request.env["devise.mapping"] = Devise.mappings[:user] 
# ./spec/requests/api/v1/sessions_spec.rb:21:in `block (3 levels) in <top (required)>' 

. 질문의 해결책은 여기 (How to write controller tests when you override devise registration controller?)는 스펙의 before 블록에 아래 코드를 넣으려고했다.

before :each do 
    request.env['devise.mapping'] = Devise.mappings[:user] 
end 

하지만 내 컨트롤러에, 나는 말한다 다른 오류 얻을 추가 할 때 :

1) API::V1::SessionsController POST /sessions on success, returns the user's  authentication token 
Failure/Error: request.env['devise.mapping'] = Devise.mappings[:user] 
NoMethodError: 
    undefined method `env' for nil:NilClass 
# ./spec/requests/api/v1/sessions_spec.rb:7:in `block (2 levels) in <top (required)>' 

여기에 또 다른 질문의 솔루션 (undefined method 'env' for nil:NilClass)이 사양에 include Devise::TestHelpers를 추가하는 시도라고하지만을 나는 그렇게 할 때 같은 오류가 반환됩니다. I가 사용하고

현재 보석 :

레일 (4.0.2)

레일-API (0.2.0)

RSpec에 레일 (2.14.1)

고안 https://lucatironi.github.io/tutorial/2012/10/15/ruby_rails_android_app_authentication_devise_tutorial_part_one/

: 가이드의 일종으로이 두 가지 튜토리얼을 사용하여 (3.2.2)

http://commandercoriander.net/blog/2014/01/04/test-driving-a-json-api-in-rails/

감사합니다. 감사합니다.

2) You are testing a Devise controller bypassing the router. 
     If so, you can explicitly tell Devise which mapping to use: 

     @request.env["devise.mapping"] = Devise.mappings[:user] 

답변

7

가 나는 문제를 해결 한 것 같아요 :

1

오류 메시지가 특별히 사용하는 제안

@request.env['devise.mapping'] = Devise.mappings[:user] 

통지

request.env['devise.mapping'] = Devise.mappings[:user] 

를 교체합니다. 내가 API를 네임 스페이스 블록 외부 devise_for에 추가했다 보인다

MyApplication::Application.routes.draw do 

    devise_for :users, skip: [:sessions, :passwords, :registrations] 

    namespace :api, defaults: { format: :json } do 
    namespace :v1 do 
     devise_scope :user do 
     post 'sessions' => 'sessions#create', :as => 'login' 
     end 
    end 
    end 
end 

내가 테스트 할 때 내가 다른 어떤 문제로 실행 긴 경우에는 조금 열어 질문을 유지합니다.

+0

불행히도 요청 앞에 @가 있든 없든 동일한 오류가 발생합니다. –

+0

'routes.rb' 파일에서 특정 경로를 공유 할 수 있습니까? 질문을 업데이트하십시오. –

+0

이미 질문이 있으니 첫 번째 코드 상자에서 아래로 스크롤하십시오. –