为什么要用factory_girl
在写测试的时候,经常需要构造数据。
而对于我们所要构造的数据:
- 除特殊原因,我们需要构建合法的数据
- 对于绝大多数测试数据,我们只在乎部分字段(和被测试内容相关的),换句话说,剩下的字段可以是默认的。
而factory girl刚好为解决这些问题提供了一个方便的机制。
factory_girl的使用
-
原则
factory的wiki解释是: factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
既一个用来创建对象的地方,而这个地方并不需要我们关注细节。在写测试的时候,我们应该尽可能把数据创建,放到factory_girl里面。
这样做的好处是:
一,重用。
二,提供了抽象,让我们更加关注所要进行测试的那一部分,而不是如何构造数据。
三,便于维护。开发中,数据结构往往是变化的。我们把数据创建放在了一个部分,如果数据结构变化了,需要进行更改,只要改一个地方就好了。 -
创建对象
# 创建对象
FactoryGirl.define do
factory :user do
name "Mike"
email "user@example.com"
end
end
FactoryGirl.create(:user, name: "New Name")
# => #<AdminUser: name: "New Name", email: "email "user@example.com")# 唯一字段 factory :user do sequence(:email) { |n| "user-#{n}@example.com" } end # 每次产生不一样的字段,假设我们使用了Faker这个gem factory :user do sequence(:name) { Faker::Name::name } end # 一次创建多个对象 FactoryGirl.create_list(:user, 2) # 创建两个user
-
创建带关联的对象
# 关联 FactoryGirl.define do factory :user do email "user@example.com" end factory :post do user end end # 相当于 user = User.new user.email = "user@example.com" user.save! post = Post.new post.user = user post.save! # 多态 FactoryGirl.define do factory :post do association :author, factory: :user end end # 一对多 FactoryGirl.define do factory :post do name "post-name" factory :post_with_comments do after(:create) do |post, evaluator| create_list(:comment, 5, post: post) end end end end # 设置一对多的数量 FactoryGirl.define do factory :post do name "post-name" factory :post_with_comments do transient do comments_count 5 end after(:create) do |post, evaluator| create_list(:comment, evaluator.comments_count, post: post) end end end end create(:post_with_comments, 2) # 有五个comments的post create(:post_with_comments, 2) # 有两个comments的post