Я пытаюсь следовать новому соглашению о тестировании Rails с этим новым проектом, над которым я работаю. Поэтому я настраиваю модульные тесты, запрашиваю тесты и функциональные тесты. Проблема заключается в том, что в тестах на запрос Capybara и информация о сеансе не поддерживаются.
В дополнение к настройке метода current_user в Devise, в моем приложении есть еще один аналогичный метод под названием current_client. Для некоторых моих контроллеров мне нужно проверить, вошел ли в систему current_user. Это работает с Devise authenticate_user! вызывается в before_action. Но для некоторых контроллеров мне также нужно проверить, был ли клиент выбран первым (например, если вы хотите добавить транзакции, их нужно связать с текущим клиентом, над которым выполняется работа).
Поэтому я добавил еще один метод before_action, который проверяет, был ли также выбран клиент. Это хорошо работает в функциональных тестах с Capybara, где я могу имитировать вход пользователя в систему и выбор клиента для обработки. Однако в тесте запроса, это не работает.
Сначала я пытаюсь получить доступ к конечной точке без входа пользователя в систему, и ответ не успешен (как и должно быть), и он перенаправляет на страницу входа. Но тогда мне нужно запустить свои тесты с пользователем, вошедшим в систему И выбранным клиентом. Помощники Devise предоставляют метод sign_in (user). Однако я не могу заставить свой метод current_user работать, и я не могу установить его правильно. Таким образом, эти тесты дают сбой и перенаправляют на другую страницу с просьбой выбрать клиента.
Я уже перепробовал много предложений, которые видел. Как попытка заглушить метод current_client, попытка предоставить информацию о сеансе для вызова GET. Я даже попытался проверить исходный код Devise, чтобы узнать, как они могут имитировать метод current_user в Rspec, и не смог найти, где происходит волшебство.
Вот код
Метод current_client выглядит следующим образом
def current_client
current_client ||= Client.find(session[:client_id]) if session[:client_id]
rescue ActiveRecord::RecordNotFound
current_client = nil
end
Так устанавливается, когда пользователь выбирает клиент для обработки
def set_current_client(client)
session[:client_id] = client.id
end
Это код в моем тестовом файле.
Сначала я создаю 2 пользователей, чтобы я мог проверить, что пользователь 1 не может получить доступ к транзакциям пользователя 2 по линии. (Я использую FactoryBot)
Затем я создаю 2 клиента (по одному для каждого пользователя)
RSpec.describe "Rooms", :type => :request do
let!(:user) {create(:user)}
let!(:user2) {create(:user2)}
let!(:client) {create(:client, user: user)}
let!(:client) {create(:client, user: user2)}
следующие работы
describe 'User Not Signed In' do
describe 'GET #index' do
subject { get transact_path}
it "returns an unsuccessful response" do
subject
expect(response).to_not be_successful
end
it "redirects to sign in page" do
subject
expect(response).to redirect_to (new_user_session_path)
end
end
Следующий не делает. Метод sign_in (user) работает в блоке before, и перенаправление на страницу входа не производится. Однако ответ не был успешным, потому что current_client не установлен, и я попытался установить его многими способами в блоке before без успеха.
describe 'User Signed In' do
before do
sign_in(user)
end
describe 'GET #index' do
it "returns a successful response" do
get transact_path
expect(response).to be_successful
end
end
end
Я понимаю, что лучшие практики отошли от тестов контроллеров, потому что то, что визуализированное представление или назначенная переменная экземпляра не имеет никакого отношения к контроллерам в теории. Но в моем случае я просто пытаюсь проверить свои конечные точки и сейчас не могу, потому что не могу настроить свой current_client.