Об использовании транзакции в тесте RSpec

Я встретил очень странную проблему при написании теста с использованием RSpec. Предположим, что у меня есть 2 модели: Компания и Предмет с ассоциацией Компания has_many предметов. Я также настроил database_cleaner со стратегией транзакции. Моя версия RSpec - 2.13.0, версия database_cleaner - 1.0.1, версия rails - 3.2.15, версия factory_girl - 4.2.0. Вот мой тест:

let(:company) { RSpec.configuration.company }
context "has accounts" do
  it "returns true" do
    company.items << FactoryGirl.create(:item)
    company.items.count.should > 0
  end
end
context "does not have accounts" do
  it "returns false" do
    company.items.count.should == 0
  end
end

конец

Я настроил исходную компанию для конфигурации rspec для использования в каждом тесте, потому что я не хочу воссоздавать ее в каждом тесте, потому что создание компании занимает много времени (из-за ее обратных вызовов и проверок). Второй тест не пройден, так как элемент не очищен из базы данных после первого теста. Я не понимаю почему. Если я изменю линию company.items << FactoryGirl.create(:item) в FactoryGirl.create(:item, company: company), это проходит. Так что любой орган может объяснить мне, почему транзакция не откатывается в первой ситуации. Я действительно запутался

Благодарю. Я весьма признателен.

1 ответ

Я думаю, что проблема не в откате, и мне интересно, если company.items может хранить это значение между contextс, но я не уверен.

Я не могу воспроизвести его быстро, поэтому хочу попросить вас:

  1. проверять log/test.log когда выполняется откат
  2. Как много INSERTс был сделан для company.items << FactoryGirl.create(:item)
  3. чем поменять на первом тесте > в < сюда: company.items.count.should < 0 тест провалится, но вы получите значение счетчика. Это 1 или 2?
  4. Если у вас есть отношения между Company а также Item модель как has_many/belongs_to чем я бы предложил просто использовать build(:item) который должен создать компанию для этого также:

например:

let(:item) { FactoryGirl.build(:item) }
context "has accounts"
it "returns true" do
  item.save
  Company.items.count.should == 1
end

не забудьте включить association :company линия в :itemфабрика

Подсказка:

добавить к spec_helper.rb:

RSpec.configure do |config|
  # most omitted
  config.include FactoryGirl::Syntax::Methods

и вы можете вызвать любой метод FactoryGirl напрямую, например так:

let(:item) { build(:item) }
Другие вопросы по тегам