RSpec: очистить таблицу/уничтожить объекты после каждого контекста
Как удалить объекты (в базе данных и в памяти), которые вы создали
- после каждого теста
- И после каждого контекста? (в контексте может иметь смысл строить тесты друг на друге)
Есть ли способ сделать это автоматически?
У меня есть следующая проблема:
Каждый тест сохраняет записи в базе данных. Следующий тест зависит от этих записей. Даже если бы я хотел создать тесты, зависящие от других тестов, я не смог бы, потому что порядок, в котором выполняются тесты, не контролируется.
factories.rb:
sequence(:name) { |n| "purchaser #{n}" }
organization_spec.rb:
context "when no supplier exists" do
it "finds no associated suppliers" do
purchaser = create(:organization_purchaser)
purchaser.partners.empty?.should == true
end
end
context "when one supplier exists" do
it "finds one associated suppliers" do
purchaser = create(:organization_purchaser)
supplier = create(:organization_supplier)
partnership = create(:partnership, organization: purchaser, partner: supplier)
purchaser.partners.last.name.should == "purchaser 1"
end
end
context "when two suppliers exist" do
it "finds two associated suppliers" do
purchaser = create(:organization_purchaser)
2.times do |i|
supplier = create(:organization_supplier)
partnership = create(:partnership, organization: purchaser, partner: supplier)
end
purchaser.partners.last.name.should == "purchaser 2"
end
end
Выход RSpec:
Organization
#suppliers_for_purchaser
responds
when no supplier exists
finds no associated suppliers
when two suppliers exist
finds two associated suppliers
when one supplier exists
finds one associated suppliers (FAILED - 1)
Failures:
1) Organization#suppliers_for_purchaser when one supplier exists finds one associated suppliers
Failure/Error: purchaser.partners.last.name.should == "purchaser 1"
expected: "purchaser 1"
got: "purchaser 3" (using ==)
Ответы
Ответ 1
Вы должны использовать Очистка базы данных
Все, что вам нужно сделать, это добавить следующий код в свой конфигурационный файл Rspec spec_helper.rb
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
UPDATE
В Rails 5.1 это не нужно, если вы используете config.use_transactional_tests
https://github.com/rails/rails/pull/19282
Ответ 2
Вы пытались добавить метод before?
describe MyController do
before(:each) do
User.delete_all
MyOtherModel.delete_all
...
end
Ответ 3
Я думаю, что ваш вопрос более похож на то, как я могу reset a factory девушка? Эти arent хранятся в базе данных, даже если вы удалите все, что вы все еще будете иметь проблему. При тестировании чего-то подобного мне легче просто переопределить последовательность девушек factory.
it "finds one associated suppliers" do
purchaser = create(:organization_purchaser)
supplier = create(:organization_supplier , name: "My First Supplier")
partnership = create(:partnership, organization: purchaser, partner: supplier)
purchaser.partners.last.name.should == "My First Supplier"
end
Другие вещи, которые вы, вероятно, делаете, это что-то вроде
it "finds one associated suppliers" do
purchaser = create(:organization_purchaser)
supplier = create(:organization_supplier)
partnership = create(:partnership, organization: purchaser, partner: supplier)
purchaser.partners.last.should == supplier
end
или даже
it "finds one associated suppliers" do
purchaser = create(:organization_purchaser)
supplier = create(:organization_supplier)
partnership = create(:partnership, organization: purchaser, partner: supplier)
purchaser.partners.last.name.should == supplier.name
end