1

Я пишу приложение с Rails, у которого будет REST API. Большинство контроллеров недоступны, если пользователь не авторизовался. Это делается путем вставки метода, который проверяет привилегии пользователя в before_action крючках в контроллерах. Я хочу проверить, что неавторизованные пользователи не могут получить доступ к определенным частям API. В настоящее время я делаю это так:RSpec как правильно структурировать тесты?

требуют «» rails_helper

RSpec.describe RoomsController, type: :controller do 
    ... 
    describe "while unauthenticated" do 
    before do 
     logout 
    end 

    def expect_unauth 
     expect(response).to have_http_status(:unauthorized) 
    end 

    it "GET #index returns http unauthorized" do get :index; expect_unauth end 
    it "GET #show returns http unauthorized" do get :show, {id: 1}; expect_unauth end 
    it "DELETE #destroy returns http unauthorized" do delete :destroy, {id: 1}; expect_unauth end 
    it "POST #create returns http unauthorized" do post :create, {id: 1}; expect_unauth end 
    it "PUT #update returns http unauthorized" do put :update, {id: 1}; expect_unauth end 
    end 

Это работает, но это в значительной степени то же самое для каждого контроллера. Как я могу сделать такой тест без копирования этого кода в каждом контроллере? Должен ли я даже проверить это или, поскольку это довольно просто, я должен просто предположить, что он работает и пишет тесты для конкретных функций контроллера?

Кроме того, он даже принадлежит спецификации контроллера? Может быть, это должна быть спецификация запроса?

+0

Rspec имеет функцию, называемую общими примерами. Возможно, это то, что вы ищете: http://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples –

+0

Если бы у меня было время, я бы создал для этого специальный сопоставитель. Читайте о том, как это сделать здесь: https://www.relishapp.com/rspec/rspec-expectations/v/2-4/docs/custom-matchers/define-matcher. В идеале я бы хотел, чтобы он читал 'it {should require_login}' для всех действий, определенных на контроллере, или 'it {должен требовать_login.for (: edit)', если контроллер частично открыт. Это довольно большая задача (но это окончательно выполнимо), так что получайте удовольствие от нее. :) – BroiSatse

ответ

1

Я обычно имел этот код для того же поведения:

ACTIONS = [ 
    [ :index, :get, {} ], 
    [ :show, :get, { :id => 1 }], 
    [ :delete, :destroy, { :id => 1 }] 
] 

ACTIONS.each do |action, method, params| 
    it "shout return unauthorized when #{method} #{action}" do 
    send(method, action, params) 
    expect_unauth 
    end 
end 
+0

А затем скопируйте его в каждый контроллер? Должен быть лучший способ –

+0

@ user860478 Не совсем, я объявляю метод 'check_unauthorized' в' spec_helper.rb' и вызываю его в свои модели, например, этот 'check_unauthorizes ([: index,: get ....]) '. – pierallard

1

Почему вы должны проверить expect_unauth на каждом действии контроллера?

Я предполагаю, что у вас есть проверка подлинности в ApplicationController или где-то общее для всех контроллеров. I.e., все действия API, требующие аутентификации, реагируют одинаково, когда есть несанкционированный доступ. Таким образом, излишне проверять это на каждом отдельном действии. Вы можете написать единую спецификацию, чтобы проверить, что неавторизованный доступ к системе отвечает так, как ожидалось.

В примерах, где проверяется функциональность действия, система сначала проверяет, есть ли действительный логин, а если нет, следующее ожидание в вашем тесте не удастся.

Чтобы ответить на вопрос о том, должны ли вы использовать спецификации контроллера или спецификации запроса, взгляните на rspec_api_documentation. Он объединяет спецификации запросов с генератором документации.

Если это слишком много для вас, я думаю, что для тестирования API это тонкая грань между спецификацией контроллера и спецификацией запроса. Спецификации контроллера заглушают представление, поэтому, если вы хотите что-то проверить в фактическом ответе, например, что JSON имеет в нем что-то конкретное, тогда вы будете использовать спецификации запросов.

Смежные вопросы