2015-09-23 2 views
1

Я хочу проверить свой API с RSpec.Вложенный API: ActionController :: UrlGenerationError - Нет совпадений маршрутов

Api :: V1 :: EventsController существует и имеет метод создания. Я использую simple_token_authentication и pundit для обеспечения безопасности.

routes.rb

Rails.application.routes.draw do 
    namespace :api do 
    namespace :v1 do 
     # users/ 
     resources :users, only: [:show, :update] do 
     # users/:id/events/ 
     resources :events 
     end 
    end 
    end 
end 

Spec:

RSpec.describe Api::V1::EventsController, type: :controller do 

    describe 'events#create' do 
    before { 
     @user = User.create(email: '[email protected]', password: '12345678', password_confirmation: '12345678') 
     @user.reload 
    } 

    it 'should 401 if bad credentials' do 
     # Given the user 

     # When 
     post "/api/v1/users/#{@user.id}/events", {}, 
     { 
     'x-user-email' => 'toto', 
     'x-user-token' => 'toto' 
     } 

     # Then 
     expect_status 401 
    end 
    end 
end 

И я получаю эту ошибку:

Failure/Error: post "/api/v1/users/#{@user.id}/events", {}, 
    ActionController::UrlGenerationError: 
    No route matches {:action=>"/api/v1/users/1/events", :controller=>"api/v1/events"} 

EDIT и ответ: Я был смущен и я использовал Rspec контроллер когда я хотел использовать запрос rspec. Вот мой рабочий пример:

RSpec.describe Api::V1::EventsController, type: :controller do 

    describe 'events#create' do 
    before { 
     @user = User.create(email: '[email protected]', password: '12345678', password_confirmation: '12345678') 
     @user.reload 
    } 

    it 'should 401 if bad credentials' do 
     # Given the user 

     # When 
     post "/api/v1/users/#{@user.id}/events", {}.to_json, 
     { 
     'Accept' => 'application/json', 
     'Content-Type' => 'application/json', 
     'x-user-email' => 'toto', 
     'x-user-token' => 'toto' 
     } 

     # Then 
     expect_status 401 
    end 
    end 
end 
+0

пробег реки маршруты чтобы узнать, какие существующие маршруты доступны. – hamitron

ответ

3

Метод post в контроллере спецификации принимает имя действия для первого параметра, а не путь, так что вместо того, чтобы:

post "/api/v1/users/#{@user.id}/events", #... 

попробовать:

post :create, #... 

Контрольные спецификации являются модульными испытаниями. Если вы хотите протестировать весь стек, используйте feature spec вместо спецификации контроллера.

+0

спасибо. Я не понял, что тесты контроллера были модульными тестами. Сейчас я использую тесты запросов, и это работает. –

3

Вам не нужно делать запрос с полным путем, потому что вы уже тестируете Api :: V1 :: EventsController.

Так будет гораздо лучше использовать специальный синтаксис для этого:

post :create, nil, { 
    'x-user-email' => 'toto', 
    'x-user-token' => 'toto' 
} 

expect(response.response_code).to eq 401 

Если вы хотите проверить маршрут, вы должны сделать это в маршрутах спецификации:

# spec/routing/api_v1_events_routing_spec.rb 
require "spec_helper" 

RSpec.describe Api::V1::EventsController do 
    describe "routing" do 
    it "#create" do 
     expect(post: "/api/v1/users/1/events").to \ 
     route_to(controller: "api/v1/events", action: "create", user_id: "1") 
    end 
    end 
end 
Смежные вопросы