factory_bot build_stubbed 策略

6

factory_bot构建策略文档中写道:

factory_bot支持几种不同的构建策略:build,create,attributes_for和build_stubbed

并且继续提供了一些使用示例。然而,它没有清楚地说明每个策略的结果是什么。我已经使用createbuild有一段时间了。从描述中,attributes_for似乎很简单,我也看到了一些用途。但是,什么是build_stubbed?描述说:

返回一个所有定义属性都被存根处理的对象

"存根处理"是什么意思?这与createbuild有何不同?

1个回答

12

让我们以这些工厂为例来考虑它们之间的差异:

FactoryBot.define do
  factory :post do
    user
    title { 'Post title' }
    body { 'Post body' } 
  end
end

FactoryBot.define do
  factory :user do
    first_name { 'John' }
    last_name { 'Doe' }
  end
end

构建

使用构建方法非常容易。它返回一个未保存的Post实例。

# initialization
post = FactoryBot.build(:post)

# call

p post
p post.user

# output
#<Post:0x00007fd10f824168> {
   :id => nil,
   :user_id => nil,
   :title => "Post title",
   :body => "Post body",
   :created_at => nil,
   :updated_at => nil
}

#<User:0x00007f8792ed9290> {
  :id => nil,
  :first_name => "Post title",
  :last_name => "Post body",
  :created_at => nil,
  :updated_at => nil
}

Post.all # => []
User.all # => []

创建

使用create方法非常明显,它会保存并返回一个Post实例。但是,它会调用所有验证和回调函数,并创建与之关联的User实例。

# initialization
post = FactoryBot.create(:post)

# call

p post
p post.user

# output

#<Post:0x00007fd10f824168> {
   :id => 1,
   :user_id => 1,
   :title => "Post title",
   :body => "Post body",
   :created_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00,
   :updated_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00
}
#<User:0x00007f8792ed9290> {
  :id => 1,
  :first_name => "John",
  :last_name => "Joe",
  :created_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00,
  :updated_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00
}

数据库中创建了帖子记录和相关用户记录:

Post.all # => [<Post:0x00007fd10f824168> {...}]

# User also created in the database
User.all # => [<User:0x00007f91af405b30> {...}]

build_stubbed

build_stubbed 模拟创建。它设置了 idcreated_atupdated_atuser_id 属性的值。此外,它跳过所有验证和回调。

Stub 表示 FactoryBot 仅初始化对象并分配给 idcreated_atupdated_at 属性的值,以使其看起来像已经创建了。对于 id,它将指定整数号码 1001(1001 只是 FactoryBot 使用的默认编号),对于 created_atupdated_at,它会分配当前日期时间。对于每个使用 build_stubbed 创建的其他记录,它将递增要分配给 id 的编号。首先,FactoryBot 初始化一个 user 记录,并将 id 属性设为 1001,但不保存到数据库中,然后初始化 post 记录,并将 id 属性设置为 1002,将 user_id 属性设置为 1001 以进行关联,但也不将记录保存到数据库中。请参见下面的示例。

#initialization
post = FactoryBot.build_stubbed(:post)

# call

p post
p post.user

# output
# It looks like persisted instance
#<Post:0x00007fd10f824168> {
   :id => 1002,
   :user_id => 1001,
   :title => "Post title",
   :body => "Post body",
   :created_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00,
   :updated_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00
}

#<User:0x00007f8792ed9290> {
  :id => 1001,
  :first_name => "John",
  :last_name => "Joe",
  :created_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00,
  :updated_at => Sat, 18 Jun 2022 05:32:17.122906000 UTC +00:00
}

无法在数据库中创建帖子和用户记录!!!

# it is not persisted in the database
Post.all # => []

# Association was also just stubbed(initialized) and there are no users in the database.
User.all # => []

谢谢你的回答。我还是不明白it stubs id, created_at, updated_at"和user_id的含义。build_stubbed方法的输出和create方法的输出有什么区别?我看到iduser_id`值不同,但为什么呢?你能详细解释一下吗? - Code-Apprentice
另外,您能展示创建每个输出块的调用吗? - Code-Apprentice
2
我已经更新了我的回答。希望现在更清晰了;) - Yurii Stefaniuk
谢谢您提供的详细信息,我相信它解决了我的疑惑。我需要直接再多操作一下才能确定。 - Code-Apprentice

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