FactoryBot 工厂中的“瞬态 do”块的目的是什么?

在 FactoryBot 工厂中使用 transient do的目的是什么?

我见过很多工厂都是从下面这样的东西开始的。

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

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

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

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

32367 次浏览

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

假设您有一个名为 car的模型,它具有以下属性:

  • 姓名
  • 购买价格
  • 模特

在工厂中创建汽车模型时,需要将汽车名称大写。我们能做的是:

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"

希望能有帮助。

瞬态属性本质上是工厂本地的变量,它们不会持久存储到创建的对象中。

我看到了瞬态属性的两个主要用途:

  • 控制/改变相关对象的创建(例如,event _ count)。
  • 改变分配给其他属性分配的值(例如,未售出)。

当然,在创建对象期间,您可以将这些瞬态属性用于您需要编写的任何其他内容。

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

这使您的测试可以表达一个概念(类似于 trait) ,而不需要知道任何关于实现的信息:

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

在我看来,我会坚持使用那些有效的特性(比如上面提到的未售出的特性)。但是当您需要传递一个非模型值(例如 event _ count)时,可以使用瞬态属性。