Rails测试《六》实战单元测试2014-03-15用factory-girl替换fixtures来创建模拟数据2上一篇我们介绍了factory-girl,这是一个很好的工具,可以用来替代rails中的fixtures,用来生成模拟数据。它直观,易读,易读就易维护。最重要的一点是,它是面向model的,面向业务的,面向应用的,而fixtures模拟的数据是面向数据库的。但是我们的单元测试,功能测试,甚至将来要介绍的集成测试,都是面向业务的,从业务角度出发的测试,测试系统是否满足业务需求。所以好处显而易见了,相信大家在使用了以后会有一点感触。上篇我们介绍了一些基本的使用,创建单个model的模拟对象,填充属性的值。
FactoryGirl.define dofactory :user_valid, :class => :User donickname "nickname"email "ee@123.com"password "123"password_confirmation "123"end factory :user_invalid_password_do_not_match, :class => :User donickname "nickname2"email "ee2@123.com"password "1232"password_confirmation "123"end end
上面模拟了两个user对象,一个有效的,一个无效的(因为密码不匹配)。通过user = FactoryGirl.build(:user_valid)就可以访问到factory-girl模拟的数据,进而在单元测试及功能测试中使用这些模拟的数据。但是有时候我们有更高的要求,比如说我们的实体是有关系的,has_many,belongs_to,has_and_belongs_to_many等等。是否能在创建model的同时,也创建它的关联实体?答案是:可以。举一个简单的关系吧。就拿我的blog项目。post和category,一个post属于一个category,一个category包含多个post。
class Post < ActiveRecord::Base belongs_to :category end class Category < ActiveRecord::Base has_many :posts end
我们可以像下面这样做。
FactoryGirl.definedofactory :category dotitle "category"endfactory :category_valid, :class=>:Category dotitle "categorytitle"end endFactoryGirl.definedo factory :post_valid_with_category1, :class => :Post dotitle "post"slug "slug"summary "summary"content "content"category endfactory :post_valid_with_category2, :class => :Post dotitle "post"slug "slug"summary "summary"content "content"association :category, :factory => :category_valid endend
上面显示我们用两种方式模拟了两个category,两个post,并且在post中指定了对应的category。
build(:post_valid_with_category1).category.title="category" build(:post_valid_with_category1).category.title="categorytitle"
我们可以像上面这样使用,就可以访问到post模拟对象的category模拟对象。还有一种办法,利用alias别名。假设我们的user和post和commenter是下面的关系。
class User < ActiveRecord::Base attr_accessible :first_name, :last_name has_many :posts endclass Post < ActiveRecord::Base attr_accessible :title belongs_to :author, :class_name => "User", :foreign_key => "author_id"endclass Comment < ActiveRecord::Base attr_accessible :content belongs_to :commenter, :class_name => "User", :foreign_key => "commenter_id"end
你就可以像下面这样创建模拟数据。
factory :user, aliases: [:author, :commenter] dofirst_name"John"last_name "Doe"endfactory :post doauthor # instead of # association :author, factory: :user title "How to read a book effectively"endfactory :comment docommenter # instead of # association :commenter, factory: :user content "Great article!"end
使用alias别名,给user对象起了两个别名,一个给post用,一个给comment用。别名分别对应于post和comment的两个属性。本文出自 “突破中的IT结构师” 博客,请务必保留此出处http://virusswb.blog.51cto.com/115214/1076695查看本栏目更多精彩内容:http://www.bianceng.cn/Programming/project/