为什么模型在重新加载后在数据库中包含旧数据?
Why model contains old data in DB after reload?
before(:all) 不应该只执行一次吗?在我的示例中,底部测试失败,因为数据库记录包含旧数据(名称 == "John")。为什么这样?我在上面的测试中将其更改为 "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
结束
此答案假定在您的 rails_helper.rb
或 spec_helper.rb
中有一行 config.use_transactional_fixtures = true
.
您的测试所做的是 运行 每个测试都在一个专用事务中,并在测试完成后回滚该事务。
您的第一个测试会将 @widget
名称更改为 Irow
,成功通过并将更改回滚到数据库。
这会让您在测试后处于
@widget.name == "Irow"
但是
@widget.reload.name == "John"
由于将名称更改为 Irow
的事务已回滚,因此数据库中的行再次具有 John
。
另一件值得一提的事情是,您可能 运行 以随机顺序进行测试 (config.order = :random
),因此如果您不是 运行 每个,您的测试就会闪烁在专用事务中进行测试。
尽量使您的测试尽可能独立,仅在确实有意义时才使用before(:all)
(也许对于一些非常昂贵的操作)。
before(:all) 不应该只执行一次吗?在我的示例中,底部测试失败,因为数据库记录包含旧数据(名称 == "John")。为什么这样?我在上面的测试中将其更改为 "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
结束
此答案假定在您的 rails_helper.rb
或 spec_helper.rb
中有一行 config.use_transactional_fixtures = true
.
您的测试所做的是 运行 每个测试都在一个专用事务中,并在测试完成后回滚该事务。
您的第一个测试会将 @widget
名称更改为 Irow
,成功通过并将更改回滚到数据库。
这会让您在测试后处于
@widget.name == "Irow"
但是
@widget.reload.name == "John"
由于将名称更改为 Irow
的事务已回滚,因此数据库中的行再次具有 John
。
另一件值得一提的事情是,您可能 运行 以随机顺序进行测试 (config.order = :random
),因此如果您不是 运行 每个,您的测试就会闪烁在专用事务中进行测试。
尽量使您的测试尽可能独立,仅在确实有意义时才使用before(:all)
(也许对于一些非常昂贵的操作)。