rspec /测试AR对象而不重新加载

时间:2018-05-15 18:04:40

标签: ruby-on-rails testing rspec

使用工厂机器人,创建如下变量:

let!(:deal) { create(:deal) }

以下示例:

expect {
  ...stuff that effectively associate an attachment to the deal...
}.to change { deal.attachments.length }.from(0).to(1)

没有通过。

同样的测试,在重新加载交易时:

...to change { deal.reload.attachments.length } ...

确实通过了。

在频繁的其他场合,我最终使用这种reload方法。感觉这不是正确的方式,而且我错过了这一点

在不重新加载记录的情况下测试记录更改的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

让我们谈谈发生了什么:

deal.attachments被调查两次,一次在调用expect块之前,然后一次,以比较差异。

因为rails知道数据库的成本很高(性能方面),所以它会缓存has_many关系的值以节省性能。因此,第一次调用deal.attachments是实际进行数据库查询的唯一时间。添加reload强制第二个数据库查询,为您提供所期望的结果。

因此,这归结为“我如何确保每次都查询数据库?”

您正在使用的方法是我认为可以接受的方法,但还有其他一些选择。我建议使用的是count而不是length

  

这将使用SQL执行计数。

这可以保证在调用expect块之前和之后进行SQL查询。

expect {
  ...stuff that effectively associate an attachment to the deal...
}.to change { deal.attachments.count }.by(1)