测试 使用 fabrication 准备测试用数据

kikyous · 2016年04月29日 · 2566 次阅读

转载自我的博客 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条记录:

  • 1 个 company
  • 2 个 staff,与每个 staff 关联的 user
  • 3 个 stock, 与每个 stock 关联的 product

继承

如果每次要生成一个完备的公司都要写上面一大堆,岂不是很烦恼!为什么不直接定义一个表示完备公司的 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)来生成一个和上面一样的公司了!

READ MORE

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号