Rspec/FactoryGirl: состояние чистой базы данных
Я новичок в Rspec и Factory girl и хотел бы, чтобы мой тест работал в определенном состоянии базы данных. Я понимаю, что я могу заставить Factory girl создать эти записи, и объекты будут уничтожены после тестового прогона, но что произойдет, если у меня есть данные в базе данных.
Например: я хочу, чтобы мой тест запускался, когда в базе данных было 3 записи, которые я создал через Factory Girl. Однако в настоящее время у меня уже есть одна модельная запись в базе данных, и я не хочу ее удалять только для теста. Наличие этой 1 модели там разрушает мой тест.
Содержимое базы данных
[#<Leaderboard id: 1, score: 500, name: "Trudy">]
leaderboard_spec.rb
require 'spec_helper'
describe Rom::Leaderboard do
describe "poll leaderboard" do
it "should say 'Successful Run' when it returns" do
FactoryGirl.create(:leaderboard, score: 400, name: "Alice")
FactoryGirl.create(:leaderboard, score: 300, name: "Bob")
FactoryGirl.create(:leaderboard, score: 200, name: "John")
Leaderboard.highest_scorer.name.should == "Alice"
end
end
end
Теперь мой тест потерпит неудачу, потому что он ошибочно предположит, что Trudy является самым лучшим бомбардиром, поскольку тест прошел в неправильном состоянии.
Предполагается ли фабричная девушка в любом случае удалить записи из базы данных, а затем отменить это удаление? Подобно тому, как он создает записи в базе данных и rollsback
Ответы
Ответ 1
Его популярно использовать драгоценный камень database_cleaner
. Вы можете найти это здесь:
https://github.com/bmabey/database_cleaner
В документации рекомендуется следующая конфигурация для rspec:
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Это позволит вам убедиться, что у вас есть чистая база данных для каждого теста.
Ответ 2
Чтобы ответить на ваш ответный вопрос как можно более прямо: нет способа отменить удаление в рамках теста.
Следуя тестовым соглашениям, ваша цель обычно состоит в том, чтобы начать с чистого листа и использовать factory_girl для эффективного создания сценария в базе данных, для которой вам нужно протестировать.
Вы можете выполнить то, что хотите, например, добавив это в свой файл factoryboards.rb:
factory :trudy do
id 1
score 500
name "Trudy"
end
Или вы можете создать простую вспомогательную функцию в тестовом файле, которая восстанавливает эту запись, когда это необходимо для тестов:
def create_trudy
FactoryGirl.create :leaderboard,
id: 1,
score: 500,
name: "Trudy"
end
end
Или вы можете разместить все это в предыдущем (: suite) в описываемом блоке, например:
describe "with a leaderboard record existing" do
before(:each) do
FactoryGirl.create :leaderboard, id: 1, score: 500, name: "Trudy"
end
# Tests with an initial leaderboard record
end
describe "with no leaderboard records initially" do
# Your test above would go here
end
В этом окончательном предложении ваши тесты становятся очень описательными, и при просмотре вывода вы точно знаете, в каком состоянии ваша база данных находилась в начале каждого теста.
Ответ 3
У меня было много проблем, пытаясь заставить эту конкретную строку не вызывать проблем в моем spec_helper.rb
, но в конце концов я обнаружил, что добавляю это прямо перед тем, как последний конец внизу сработал
config.before(:all) do
FactoryBot.reload
end