Rails测试《五》实战单元测试

用factory-girl替换fixtures来创建模拟数据

fixtures

在前面我们介绍了,rails的测试系统默认使用fixtures来创建模拟数据,这些数据以yaml的格式书写,放在db/fixtures文件夹中,每个model都有一个对应的文件,test/fixtures/users.yml。

在测试启动的时候这些fixtures中的数据会加载到测试数据库,并且加载到变量中,供单元测试和功能测试使用。

使用fixtures有几个不利的因素,使得他们处于不利的位置。

最主要的一个因素是,这些fixtures描述的数据和测试他们的行为是分开的,在不同的文件中。使用这些模拟数据,我们需要依赖于fixtures文件,这些文件很难阅读,维护不便。

假设我们需要两个user对象,用来测试我们的User.authenticate是否工作正常,我们需要编写下面的内容。

bob:
  username: bob
  email: bob@example.com
  password_digest: 3488f5f7efecab14b91eb96169e5e1ee518a569f
  password_salt: bef65e058905c379436d80d1a32e7374b139e7b0 

admin:
  username: admin
  email: admin@example.com
  password_digest: 3488f5f7efecab14b91eb96169e5e1ee518a569f
  password_salt: bef65e058905c379436d80d1a32e7374b139e7b0

因为这两个数据需要存储到数据库中,我们的password_digest和password_salt需要是上面的样子,我们无法知道这两个属性的值具体代表什么意义,它们的内容到底是什么呢?

在http://guides.rubyonrails.org/testing.html的最后面的部分,推荐了一个fixtures的替代品,那就是factory girl,它还有一个rails版本factory girl rails,专门用于rails的测试。

如何在rails中使用factory girl rails

在https://github.com/thoughtbot/factory_girl/wiki有关于factory-girl使用的详细教程,基本上也适用于factory-girl-rails。

下面我们介绍一下基本的使用方法。

首先在gemfile文件中加入

gem 'factory_girl_rails'

然后执行

bundle install

然后再test目录创建factories.rb文件。这个文件的作用有点像我们使用fixtures的时候的yml文件,里面用来创建模拟数据。但是不同的是fixtures中的数据会被自动加入数据库,所以创建的时候声明的属性要和数据库匹配,是一种从数据库出发的模拟数据。但是factory-girl创建的模拟数据不会被自动加入数据库,是一种从model出发的模拟数据,所以声明的属性是和model对应的,所以不会出现使用fixtures的时候的哪种看不懂的password_digest属性值。

FactoryGirl.define do
  factory :user do
    nickname "nickname"
    email "ee@123.com"
    password "123"
    password_confirmation "123"
  end
end

上面factory-girl创建了一个user对象,这个对象也同样可以在测试用使用。请注意factory :后满的内容,这样要对应于一个model的类名,第一个字母最好小写,当然大写也是可以的。

还需要在使用这些数据的地方引入一个module。假如我们想要在user的单元测试中使用factory-girl的模拟数据,可以向下面这样添加这个module。

class UserTest < ActiveSupport::TestCase
  include FactoryGirl::Syntax::Methods
end

这样的话,我们就可以在user的单元测试中像下面这样使用这些模拟数据。

# 保存user数据到数据库
user = create(:user) 

# 不保存user数据,只是把它保存到user变量
user = build(:user) 

# 获取factory-girl中定义的user属性的键值对hash
user_attributes = attributes_for(:user) 

# 创建一个user的stub对象
user_stub = build_stubbed(:user) 

# 覆盖factory-girl中user对象的部分属性
user = create(:user, first_name: 'Joe')

但是,如果我们有很多的model,都需要模拟数据,都写在factories.rb文件中,好像不太好,越写越长,而且内容混杂,也不好维护,也不利于阅读。

我们可以在创建test/factories文件夹,然后再test/factories文件夹中创建users.rb,在users.rb中写user的模拟数据。同样可以在factories文件夹中创建模拟其他model用的文件。

但是上面的factory-girl只是创建了一个user对象,如果需要多个模拟的user对象呢?可以像下面这样写,用:class => :User,来指定当前这个对象使用user的model为模板。

FactoryGirl.define do
  factory :user1, :class => :User do
    nickname "nickname"
    email "ee@123.com"
    password "123"
    password_confirmation "123"
  end
  factory :user2, :class => :User do
    nickname "nickname2"
    email "ee2@123.com"
    password "1232"
    password_confirmation "123"
  end
end

上面创建了两个user对象。可以像下面这样使用它们。

def test_use_valid_user_from_factory_girl
   user = build(:user1)
   assert user.valid?
 end 

 def test_use_invalid_user_from_factory_girl
   user = build(:user2)
   assert user.invalid?
 end

我已经在https://github.com/woaigithub/blog中加入了大量的unit test,大家可以参考,也可以提出意见,欢迎大家提意见!

本文出自 “突破中的IT结构师” 博客,请务必保留此出处http://virusswb.blog.51cto.com/115214/1076069

查看本栏目更多精彩内容:http://www.bianceng.cn/Programming/project/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据模拟
, 文件
, 数据
, 对象
, setup factory
, 单元测试
, 模拟
user
rails 单元测试、android 单元测试实战、rails 实战圣经、rails实战、rails 测试,以便于您获取更多的相关知识。

时间: 2024-08-02 07:47:51

Rails测试《五》实战单元测试的相关文章

Rails测试《六》实战单元测试

用factory-girl替换fixtures来创建模拟数据2 上一篇我们介绍了factory-girl,这是一个很好的工具,可以用来替代rails中的fixtures,用来生成模拟数据. 它直观,易读,易读就易维护.最重要的一点是,它是面向model的,面向业务的,面向应用的,而fixtures模拟的数据是面向数据库的.但是我们的单元测试,功能测试,甚至将来要介绍的集成测试,都是面向业务的,从业务角度出发的测试,测试系统是否满足业务需求.所以好处显而易见了,相信大家在使用了以后会有一点感触.

Rails测试《四》实战单元测试unit test

之前的博客介绍了一些rails测试相关的知识.测试文件的位置,测试的类型,测试常用命令,以及可用的一些资源,以及如何利用fixtures生成模拟数据. 今天我们来实际的写一下单元测试,用到的知识主要是fixtures和unit test.fixtures用来模拟数据,unit test就是我们今天的主角-单元测试. 今天的代码将以blog项目为背景,为这个项目写一些单元测试. 这个项目的代码可以在https://github.com/woaigithub/blog获取到,而且项目已经部署到htt

Rails测试《十》不能错过的杂七杂八

今天来介绍一些杂七杂八的测试知识,但是它们是不能错过的. 首先来介绍一下常用的测试命令 rake test 运行包括单元测试.功能测试和集成测试在内的所有测试. rake test:units 运行所有的单元测试. rake test:functionals 运行所有的功能测试 rake test:integration 运行所有的集成测试. rake test:recent 运行最近修改过的测试. rake test:uncommited 运行所有未提交的测试.支持svn和git. setup

Rails测试《三》功能测试functional test

功能测试functional test 在rails中,针对单个controller中的各个action进行的测试,叫做功能测试.controller处理web的请求,将请求的响应render到view中. 功能测试包括的内容 web请求是否成功? 用户是否被引导进入正确的页面? 用户是否成功的验证? 响应的模板中是否包含了正确的内容? 在给用户的view中是否显示了适当的内容? 功能测试分解 在使用rails g scaffold post或者rails g controller命令之后,会创

Rails测试《一》fixtures简介

简介 每个rails应用都包括三个环境: 生产环境 开发环境 测试环境 我们的测试就是跑在测试环境,如果测试涉及数据库,会在测试数据库进行操作.这样不会对生产环境和开发环境的数据造成影响. 我们先使用 rails new projects 命令来创建一个rails应用,默认会给我们创建一个projects目录,里面会包含一些默认的目录和文件.其中有一个文件夹test,里面将会放我们全部的测试相关文件. $ ls -F test/ fixtures/       functional/     i

《手机测试Robotium实战教程》目录—导读

作者简介 手机测试Robotium实战教程 杨志伟,从2011年开始接触移动端自动化测试工作,积累了丰富的自动化测试案例实战经验,擅长整合主流无线端自动化测试框架的运用.曾就职于知名外企RingCentral,负责Mobile自动化测试框架的开发和持续改进工作:现就职于网龙网络有限公司,负责BDD模式的运用和推广工作. 本书特色 国内第一本原创的Robotium图书 紧跟移动平台开发.测试的热点技术 全面讲解了用Robotium建立测试工程.测试项目搭建.自动化测试脚本编写.测试框架完善.Rob

《手机测试Robotium实战教程》——第2章,第2.1节JDK安装及其环境变量配置

第2章 测试开发环境搭建 手机测试Robotium实战教程 2.1 JDK安装及其环境变量配置 因为要用到Java语言,所以JDK是首先需要安装的.可以通过下面的链接,选择对应平台的JDK版本进行下载. http://www.oracle.com/technetwork/java/javase/downloads/index.htm. 本书所有的例子选择在JDK 8平台下进行. 运行下载的JDK安装文件,根据提示完成安装.在安装完毕后,设置环境变量.设置环境变量的目的是可以在任意路径下执行jav

《手机测试Robotium实战教程》—第2章2.1节JDK安装及其环境变量配置

第2章 测试开发环境搭建 手机测试Robotium实战教程2.1 JDK安装及其环境变量配置 因为要用到Java语言,所以JDK是首先需要安装的.可以通过下面的链接,选择对应平台的JDK版本进行下载. 本书所有的例子选择在JDK 8平台下进行. 运行下载的JDK安装文件,根据提示完成安装.在安装完毕后,设置环境变量.设置环境变量的目的是可以在任意路径下执行javac/java等工具. (1)在计算机桌面选中计算机后单击鼠标右键,在弹出的菜单中选择"属性"项,打开"系统属性&q

《手机测试Robotium实战教程》——第1章,第1.1节何为自动化测试

第1章 自动化测试简介手机测试Robotium实战教程 1.1 何为自动化测试什么是自动化测试?在一些人眼中,觉得自动化测试是一种比较高大上的东西.但在我看来,自动化测试其实就是通过一定的编程手段,自动执行本来需要手动执行的一系列测试的活动.只要有一定的编程基础,人人都可以参与到自动化测试中来,享受到自动化测试带来的便捷性.现在有很多商业的.开源的自动化测试工具可以更好.更容易地帮助我们进行自动化测试,因此,自动化测试的门槛并没想象中高. 举个小例子来说明自动化测试是怎样让我们的生活变得美好的.