Reputation: 1310
Should not before(:all) be executed only once? In my example the bottom test fails, because db record contains old data (name == "John"). Why so? I changed it in test above it to "Irow".
describe "Widget" do
before(:all) do
@widget = Widget.create(name: "John")
end
it "changes Widget's #name in DB" do
expect do
@widget.name = "Irow"
@widget.save!
end.to change { @widget.reload.name}.from("John").to("Irow")
end
it "#name must be updated in DB by previous test" do
expect(@widget.reload.name).to eq("Irow") # failing test
end
end
Upvotes: 1
Views: 101
Reputation: 5313
This answer assumes that either in your rails_helper.rb
or spec_helper.rb
there is a line config.use_transactional_fixtures = true
.
What your tests are doing is running each test in a dedicated transaction and rolling back said transaction after the test is finished.
Your first test will change the @widget
name to Irow
, pass successfully and rollback the changes to the database.
This puts you in a state where after this test
@widget.name == "Irow"
but
@widget.reload.name == "John"
as the transaction which changed the name to Irow
was rolled back, so the row in database has John
again.
The other thing worth mentioning is that you might be running your tests in a random order (config.order = :random
), thus your tests would be blinking if you were not running each test in a dedicated transaction.
Try to make your tests as isolated as possible, use before(:all)
only if it really makes sense (perhaps for some really expensive operations).
Upvotes: 1