но я думал, что FactoryBot берет на себя все создание модели в тестах.
Нет - FactoryBot просто предоставляет фабрики, которые создают экземпляры модели. Это широко используется в качестве замены для приспособлений для заполнения базы данных перед тестами. В отличие от приборов это не происходит автоматически.
Простое добавление FactoryBot абсолютно ничего не меняет в вашем приложении, кроме того факта, что генераторы создадут заводской файл. Это никак не влияет на поведение ваших моделей.
При тестировании создания ресурсов вам необходимо проверить, что:
- При наличии правильных параметров, модель должна сохранятьсяв базу данных
- Если заданы действительные параметры, то ответ должен быть успешным и указать на вновь созданный ресурс.
- Если заданы недопустимые параметры, модель не должна сохраняться в базе данных
- Если указаны недопустимые параметры, ответ должен быть 422. Должна быть отображена страница с ошибкой.
Вы хотите проверить это с помощью спецификации запроса, а не спецификации контроллера.
Спецификации запроса предоставляют высокоуровневую альтернативу спецификациям контроллера. Фактически, начиная с RSpec 3.5, команды Rails и RSpec не рекомендуют напрямую тестировать контроллеры в пользу функциональных тестов, таких как спецификации запросов.
require "rails_helper"
RSpec.describe "Chatroom creation", type: :request do
let(:valid_params) do
{
chatroom: {
topic: "test chatroom",
slug: "code-testing",
description: "Testing with Rspec"
}
}
end
let(:invalid_params) do
{
chatroom: {
topic: ''
}
}
end
context "when the parameters are valid" do
it "creates a new chatroom" do
expect do
post '/chatrooms', params: valid_params
end.to change(Chatroom, :count).by(1)
end
it "returns success" do
post '/chatrooms', params: valid_params
expect(response).to have_http_status(:created)
end
end
context "when the parameters are invalid" do
it "does not create a new chatroom" do
expect do
post '/chatrooms', params: invalid_params
end.to_not change(Chatroom, :count)
end
it "returns bad entity" do
post '/chatrooms', params: invalid_params
expect(response).to have_http_status(:unprocessable_entity)
end
end
end
Тогда мы можем решить проблему с вашим контроллером, которая должнапрочитайте:
class ChatroomsController < ApplicationController
# ...
def create
new_chatroom = Chatroom.new(chatroom_params)
if new_chatroom.save
new_chatroom.members.create(user_id: @current_user[:username])
render_response(new_chatroom, :created)
else
render_error_response(new_chatroom.errors, :bad_request)
end
end
end
Никогда не используйте .valid?
, чтобы проверить, была ли запись сохранена в базе данных. Это только гарантирует, что проверки на уровне модели пройдены. Не то чтобы оператор INSERT из .create
фактически создал строку в базе данных. См. Проверка опасности уникальности для примера того, что может произойти.
Хотя вы можете использовать new_chatroom.persisted?
, это идиома распространенных рельсов, поскольку она дает вам переменную, которой вы можете манипулировать дозапись сохраняется.
class ChatroomsController < ApplicationController
# ...
def create
new_chatroom = Chatroom.new(chatroom_params)
new_chatroom.members.new(user: current_user)
if new_chatroom.save
render_response(new_chatroom, :created)
else
render_error_response(new_chatroom.errors, :bad_request)
end
end
end