基本介绍
machinist(机械师)很容易在测试中使用的创建对象。它产生的属性,你不关心的数据,并构建任何必要的关联对象,让你指定只有你关心你的测试领域。
describe Comment, "without_spam scope" do
it "doesn't include spam" do
# This will make a Comment, a Post, and a User (the author of the
# Post), generate values for all their attributes, and save them:
spam = Comment.make!(:spam => true)
Comment.without_spam.should_not include(spam)
end
end
你要告诉 Machinist 怎样配合blueprints(蓝图):
require 'machinist/active_record'
User.blueprint do
username { "user#{sn}" } # Each user gets a unique serial number.
end
Post.blueprint do
author
title { "Post #{sn}" }
body { "Lorem ipsum..." }
end
Comment.blueprint do
post
email { "commenter#{sn}@example.com" }
body { "Lorem ipsum..." }
end
安装
安装后
rails generate machinist:install
如果 你想在生成 model 时 Machinist 自动与 blueprint 合作,可以在 config/application.rb 中增加这:
config.generators do |g|
g.fixture_replacement :machinist
end
一张蓝图描述了如何产生一个对象。
蓝图为您提供了一些你‘’不必需的‘’ 属性,所以在测试时你可以 ‘’更专心‘’ 于书写自己想要 ‘’测试‘’ 的东西。
一个简单的例子:
Post.blueprint do
title { "A Post" }
body { "Lorem ipsum..." }
end
然后你就可以通过
Post.make!
来构建蓝图。
对上面蓝图生成的东西,你有不满意的,可以这么做
Post.make!(:title => "A Specific Title") # 参数以 Hash 的形式
想要 ‘唯一’ 的属性,可以能过 sn 方法,生成时自带一个 ‘序列号’
User.blueprint do
username { "user-#{sn}" }
end
关联 ?可以这么做..
Comment.blueprint do
post { Post.make }
end
在生成 comment 时会生成与之关联的 post , 并被保存。 上面的代码其实还可以更简单
Comment.blueprint do
post
end
上面的 post 都是 create comment 时自动 constructing(构造)成 的,如果您想要自己定义,可以这么写。
post = Post.make(:title => "A particular title)
comment = Comment.make(:post => post)
为了 支持 has_many 和 has_and_belongs_to_many 关联,你可以这么写:
Post.blueprint do
comments(3) # Makes 3 comments.
end
命名的蓝图
举例:
User.blueprint do
name { "User #{sn}" }
email { "user-#{sn}@example.com" }
end
User.blueprint(:admin) do
name { "Admin User #{sn}" }
admin { true }
end
现在 你可以这么调用:
User.make!(:admin)
如果你使用了 ‘命名蓝图’ 你就得必需 定义 一个 default blueprint (默认的蓝图),即使它是空的 !
蓝图对 普通 的 ruby 对象也有用,比如:
class Post
extend Machinist::Machinable
attr_accessor :title
attr_accessor :body
end
现在,你可以像其它示例代码一样使用:
Post.blueprint do
title { "A title!" }
body { "A body!" }
end
其它技巧:
你可能需要一个属性的值(示例中的 body),而这个属性又是根据上一个属性的值(示例中的 author)生成(或者说‘相关’)的:
Post.blueprint do
author { "Author #{sn}" }
body { "Post by #{object.author}" }
end
其它知识
the specs 和 the spec for Machinable