`transient do`块在FactoryBot工厂中的目的是什么?

84

transient do 在 FactoryBot 工厂中有什么目的?

我见过很多以以下方式开始的工厂。

factory :car do
  owner nil
  other_attribute nil
end
...

我在这个博客上找到了一些信息:
使用 FactoryGirl 在 Rails 中轻松创建复杂数据集

但是我仍然不完全理解如何以及为什么要这样做。我的 FactoryBot 经验很少。

有没有使用 FactoryBot 有一些经验的人可以分享一些见解呢?


12
你的示例没有使用“transient”。你是否有使用“transient”的工厂需要理解? - Dave Schweisguth
2个回答

158

transient属性允许您传递模型上不是属性的数据

比如你有一个名为car的模型,其具有以下属性:

  • name
  • purchase_price
  • model

当您在工厂中创建汽车模型时,希望将汽车的名称大写。我们可以这样做:

factory :car do
  transient do
    # capitalize is not an attribute of the car
    capitalize  false
  end

  name           { "Jacky" }
  purchase_price { 1000 }
  model          { "Honda" }
 
  after(:create) do |car, evaluator|
    car.name.upcase! if evaluator.capitalize
  end
end
因此,每当您创建汽车工厂并希望将名称资本化时,可以执行以下操作。
car = FactoryGirl.create(:car, capitalize: true)
car.name
# => "JACKY"

13

瞬态属性本质上是工厂局部变量,不会持久化到创建的对象中。

我见过瞬态属性的两个主要用途:

  • 控制/改变相关对象的创建(例如 accident_count)。
  • 改变分配给其他属性赋值的值(例如 unsold)。

当然,在对象创建期间您也可以使用这些瞬态属性来编写其他任何需要的代码。

factory :car do
  transient do
    accident_count 0
    unsold false
  end

  owner unsold ? 'new inventory' : nil

  after(:create) do |car, evaluator|
    create_list(:police_report, evaluator.accident_count, vehicle: car) 
  end      
end

这使得你的测试可以表达一个概念(类似于特征),而不需要了解任何实现细节:

FactoryBot.create(:car, make: 'Saturn', accident_count: 3)
FactoryBot.create(:car, make: 'Toyota', unsold: true)

我认为,当特性可用时(例如未出售、高于),应该坚持使用特性。但是当您需要传递非模型值时(例如事故计数),瞬态属性是一种可行的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接