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