转载自我的博客 http://kikyo.us/2016/04/28/use-fabrication-to-make-testing-data.html
rails 默认用 fixture 创建测试数据,但是 fixture 直接操作数据库,不能利用 ActiveRecord,要创造复杂的数据时就会非常痛苦。 因此出现了 fabrication,factory_giri 等,在这两者中我最终选择了 fabrication,因为它更加灵活,更加优美。
https://github.com/paulelliott/fabrication
class Company < ApplicationRecord
has_many :stocks
has_many :staffs
has_many :users, through: :staffs
end
class User < ApplicationRecord
end
class Product < ApplicationRecord
belongs_to :stock
end
class Staff < ApplicationRecord
belongs_to :user
belongs_to :company
end
class Stock < ApplicationRecord
belongs_to :product
belongs_to :company
end
# 定义 company Fabricator
Fabricator(:company) do
name { SecureRandom.hex(5) }
contacts { SecureRandom.hex(3) }
phone '1111111'
end
irb(main):012:0> Fabricate(:company)
=> #<Company id: 980193688, name: "d153c213e4", contacts: "995add", phone: "1111111", created_at: "2016-04-29 01:40:26", updated_at: "2016-04-29 01:40:26">
这很简单,不值得一提对吧!
# 定义 stock Fabricator
Fabricator(:stock) do
product
company
end
Fabricator(:staff) do
user
company
end
irb(main):007:0> Fabricate(:stock)
...
SQL (0.3ms) INSERT INTO `products` (`name`, `created_at`, `updated_at`) VALUES ('44434bee4c', '2016-04-29 01:42:39', '2016-04-29 01:42:39')
SQL (0.2ms) INSERT INTO `companies` (`name`, `contacts`, `phone`, `created_at`, `updated_at`) VALUES ('01382eb7e5', '8569b3', '1111111', '2016-04-29 01:42:39', '2016-04-29 01:42:39')
SQL (0.2ms) INSERT INTO `stocks` (`product_id`, `company_id`, `created_at`, `updated_at`) VALUES (298488079, 980193691, '2016-04-29 01:42:39', '2016-04-29 01:42:39')
...
=> #<Stock id: 980193023, product_id: 298488079, company_id: 980193691, created_at: "2016-04-29 01:42:39", updated_at: "2016-04-29 01:42:39">
可以看到Fabricate(:stock)
不仅生成了 Stock 记录,还生成了与其关联的 Product 和 Company。
Fabricator(:company) do
name { SecureRandom.hex(5) }
contacts { SecureRandom.hex(3) }
phone '1111111'
staffs(count: 2){ Fabricate(:staff){ role: :admin } }
stocks(count: 3){ |attrs, i| Fabricate(:stock){ remark: "stock#{i}" } }
end
上面的 Fabricator 会生成了一个完备的公司,包括1+2+2+3+3=11
条记录:
如果每次要生成一个完备的公司都要写上面一大堆,岂不是很烦恼!为什么不直接定义一个表示完备公司的 Fabricator 呢?这个 Fabricator 继承自 Company Fabricator,理所当然。
Fabricator(:complete_company, from: :company) do
staffs(count: 2){ Fabricate(:staff){ role: :admin } }
stocks(count: 3){ |attrs, i| Fabricate(:stock){ remark: "stock#{i}" } }
end
现在可以使用Fabricate(:complete_company)
来生成一个和上面一样的公司了!