简体   繁体   English

FactoryBot 关联的存根链

[英]Stubbing Chains of FactoryBot Associations

I am working on improving my company's RSpec tests (which have gotten a bit slow), and I suspect one of the culprits is a FactoryBot factory we use in almost every test - a factory that results in a bunch of unnecessary associations due to chaining.我正在努力改进我公司的 RSpec 测试(速度有点慢),我怀疑其中一个罪魁祸首是我们在几乎所有测试中都使用的 FactoryBot 工厂——该工厂由于链接而导致一堆不必要的关联。 For example:例如:

FactoryBot.define do
  # we use a bunch of these and most tests don't care about the value of :b, 
  # but ActiveRecord validations require it
  factory :A do
    association :b
    # some other attributes with simple types
  end

  factory :B do
    association :c
  end

  factory :C do
    association :d
  end
end

How can I create an instance of A without also forcing a B , a C , and a D to get created (I am planning on controlling those with traits)?如何创建A的实例而不强制创建BCD (我计划控制具有特征的那些)? Using a build_stubbed strategy has been my best answer so far (which doesn't solve all my problems, but is pretty good), but I am curious whether there are other tricks I could shove up my sleeves.到目前为止,使用build_stubbed策略一直是我的最佳答案(这并不能解决我所有的问题,但非常好),但我很好奇是否还有其他技巧可以袖手旁观。

The problem is most likely how you create the model, and not because of FactoryBot.问题很可能是您如何创建 model,而不是因为 FactoryBot。 Let's say you have factory a with association b, c and d.假设您有工厂 a 与关联 b、c 和 d。 In order to create the model you need all associations because you have a not null dependency, in the factory file you can add the following:为了创建 model 您需要所有关联,因为您没有 null 依赖项,您可以在工厂文件中添加以下内容:

  FactoryBot.define do
    factory :a do
      b { build :b }
      c { build :c }
      d { build :d }
   end
  end

Build let you persists the association in the memory database instead of the test database, however if you are doing a specific call to that association in the code which requires a database call, for example abupdate:(some_column: value) you need to override it in the test by creating it like so create:a, b: create(:b) .构建允许您将关联保留在 memory 数据库而不是测试数据库中,但是如果您在需要数据库调用的代码中对该关联进行特定调用,例如abupdate:(some_column: value)您需要覆盖它在测试中通过像这样创建它create:a, b: create(:b)

It's also common for people to create the model every time instead of using let , which only creates the object whenever you need it instead of in a before:each for example.人们也经常创建 model 而不是使用let ,它只会在需要时创建 object 而不是在before:each例如。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM