【问题标题】:build record with has_many through association, no db通过关联与 has_many 建立记录,没有数据库
【发布时间】:2018-04-11 20:42:28
【问题描述】:

在测试给定预加载关系时不查询数据库的方法的上下文中,我想用预加载的关联构建一条记录。尝试通过关系建立具有 has_many 的记录时遇到了麻烦。这不起作用:

let(:preloaded_record) { build(:test_record,
  hmtas: build_list(:has_many_through_association, N)
) }

通过将数据持久化到数据库来建立关系,然后在数据库中查询该数据以测试方法是否不会命中数据库,这似乎不是最优的。

如何在不使用 db 的情况下通过关联使用预加载的 has_many 构建记录?

期望:具有 .association(:hmtas).loaded 的实际记录或近似模拟?

可选:使用 factory_bot

涉及:How to use build method with a has_many :through association

【问题讨论】:

  • 为什么它看起来不太理想?成本低,您不必创建解决方案,并且更接近生产环境。
  • 我尽量避免由于性能而影响数据库
  • 打分贝的性能成本是多少?
  • 我没有数字。它会减慢测试速度。我不认为它与这个问题严格相关。如果它分散注意力,也许我应该缩短上下文?感谢您提供的任何帮助
  • 查看 Max 的回答。如果数据库命中会大大减慢测试速度,我会感到惊讶。

标签: ruby-on-rails activerecord rspec factory-bot


【解决方案1】:

答案是你不知道。 ActiveRecord 关联只是关系数据库之上的抽象,没有它就没有意义 - 关联是由外键关系定义的。

这就是为什么协会没有真正提供存根的原因。

你可以stubgetter方法返回一个对象数组:

allow(parent).to receive(:children)
                  .and_return(build_list(:children, 10))

但您需要权衡敏锐度损失与可能非常微不足道的性能提升。

【讨论】:

  • 这就是我所担心的。谢谢。我仍然希望有人会想出一些东西
  • 我不得不说不要抱太大希望。您可以将 setter 和 getter 存根,以使“关联”的行为类似于常规的 ruby​​ 属性,但您可能会掩盖应用程序中的错误和错误。我会说,如果您的测试需要关联,如果您将其排除在外,您就无法正确测试它。毕竟,模型在 AR 中所做的最重要的部分是表示数据库中的行并将数据随机输入和输出。
  • 为了争论,如果我多次运行这个测试,它就会开始发挥作用。我认为这很奇怪,没有办法做到这一点。感谢您的反馈!
  • 这并不奇怪——它是故意的。 david.heinemeierhansson.com/2014/…
  • 似乎这方面的设计者非常固执地尝试通过禁止模拟数据库边界来破坏单元测试。我需要的功能测试只对加载方面感兴趣,并且非常重要,因为有很多方式可能会出现回归。将数据库单独留在这里是一个明显的优势
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
相关资源
最近更新 更多