[英]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
的实例而不强制创建B
、 C
和D
(我计划控制具有特征的那些)? 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.