Rails测试《五》实战单元测试-用factory-girl替换fixtures来创建模拟数据

简介:

fixtures

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

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

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

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

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

 
  1. bob: 
  2.   username: bob 
  3.   email: bob@example.com 
  4.   password_digest: 3488f5f7efecab14b91eb96169e5e1ee518a569f 
  5.   password_salt: bef65e058905c379436d80d1a32e7374b139e7b0 
  6.  
  7. admin: 
  8.   username: admin 
  9.   email: admin@example.com 
  10.   password_digest: 3488f5f7efecab14b91eb96169e5e1ee518a569f 
  11.   password_salt: bef65e058905c379436d80d1a32e7374b139e7b0 
  12.    

因为这两个数据需要存储到数据库中,我们的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文件中加入

 

 

 
  1. gem 'factory_girl_rails' 
然后执行
 
 
  1. bundle install 
然后再test目录创建factories.rb文件。这个文件的作用有点像我们使用fixtures的时候的yml文件,里面用来创建模拟数据。但是不同的是fixtures中的数据会被自动加入数据库,所以创建的时候声明的属性要和数据库匹配,是一种从数据库出发的模拟数据。但是factory-girl创建的模拟数据不会被自动加入数据库,是一种从model出发的模拟数据,所以声明的属性是和model对应的,所以不会出现使用fixtures的时候的哪种看不懂的password_digest属性值。
 
 
  1. FactoryGirl.define do 
  2.   factory :user do 
  3.     nickname "nickname" 
  4.     email "ee@123.com" 
  5.     password "123" 
  6.     password_confirmation "123" 
  7.   end 
  8. end 

 

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

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

 
  1. class UserTest < ActiveSupport::TestCase 
  2.   include FactoryGirl::Syntax::Methods 
  3. end 

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

 
  1. # 保存user数据到数据库
  2. user = create(:user
  3.  
  4. # 不保存user数据,只是把它保存到user变量 
  5. user = build(:user
  6.  
  7. # 获取factory-girl中定义的user属性的键值对hash 
  8. user_attributes = attributes_for(:user
  9.  
  10. # 创建一个user的stub对象 
  11. user_stub = build_stubbed(:user
  12.  
  13. # 覆盖factory-girl中user对象的部分属性
  14. 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为模板。

 
  1. FactoryGirl.define do 
  2.   factory :user1:class => :User do 
  3.     nickname "nickname" 
  4.     email "ee@123.com" 
  5.     password "123" 
  6.     password_confirmation "123" 
  7.   end 
  8.   factory :user2:class => :User do 
  9.     nickname "nickname2" 
  10.     email "ee2@123.com" 
  11.     password "1232" 
  12.     password_confirmation "123" 
  13.   end 
  14. end 

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

 
  1. def test_use_valid_user_from_factory_girl 
  2.    user = build(:user1
  3.    assert user.valid? 
  4.  end 
  5.  
  6.  def test_use_invalid_user_from_factory_girl 
  7.    user = build(:user2
  8.    assert user.invalid? 
  9.  end 

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

 




本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1076069,如需转载请自行联系原作者

目录
相关文章
|
15天前
|
存储 关系型数据库 测试技术
玩转n8n测试自动化:核心节点详解与测试实战指南
n8n中节点是自动化测试的核心,涵盖触发器、数据操作、逻辑控制和工具节点。通过组合节点,测试工程师可构建高效、智能的测试流程,提升测试自动化能力。
|
2月前
|
Web App开发 人工智能 JavaScript
主流自动化测试框架的技术解析与实战指南
本内容深入解析主流测试框架Playwright、Selenium与Cypress的核心架构与适用场景,对比其在SPA测试、CI/CD、跨浏览器兼容性等方面的表现。同时探讨Playwright在AI增强测试、录制回放、企业部署等领域的实战优势,以及Selenium在老旧系统和IE兼容性中的坚守场景。结合六大典型场景,提供技术选型决策指南,并展望AI赋能下的未来测试体系。
|
2月前
|
存储 人工智能 算法
AI测试平台实战:深入解析自动化评分和多模型对比评测
在AI技术迅猛发展的今天,测试工程师面临着如何高效评估大模型性能的全新挑战。本文将深入探讨AI测试平台中自动化评分与多模型对比评测的关键技术与实践方法,为测试工程师提供可落地的解决方案。
|
2月前
|
人工智能 缓存 测试技术
Playwright进阶指南 (6) | 自动化测试实战
2025企业级测试解决方案全面解析:从单元测试到千级并发,构建高可用测试体系。结合Playwright智能工具,解决传统测试维护成本高、环境依赖强、执行效率低等痛点,提升测试成功率,内容从测试架构设计、电商系统实战框架、高级测试策略、Docker化部署、CI/CD集成及AI测试应用,助力测试工程师掌握前沿技术,打造高效稳定的测试流程。
Playwright进阶指南 (6) | 自动化测试实战
|
20天前
|
人工智能 数据可视化 测试技术
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
264 11
|
2月前
|
资源调度 前端开发 JavaScript
Jest 测试实战指南
本文系统讲解如何使用 Jest 进行高效的 JavaScript 函数测试,涵盖环境搭建、测试用例编写、模拟函数与快照测试等内容,帮助开发者提升代码质量与测试效率。
|
2月前
|
人工智能 缓存 监控
大模型性能测试实战指南:从原理到落地的全链路解析
本文系统解析大模型性能测试的核心方法,涵盖流式响应原理、五大关键指标(首Token延迟、吐字率等)及测试策略,提供基于Locust的压测实战方案,并深入性能瓶颈分析与优化技巧。针对多模态新挑战,探讨混合输入测试与资源优化
|
4月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
747 23
|
9月前
|
数据可视化 前端开发 测试技术
接口测试新选择:Postman替代方案全解析
在软件开发中,接口测试工具至关重要。Postman长期占据主导地位,但随着国产工具的崛起,越来越多开发者转向更适合中国市场的替代方案——Apifox。它不仅支持中英文切换、完全免费不限人数,还具备强大的可视化操作、自动生成文档和API调试功能,极大简化了开发流程。
|
6月前
|
SQL 安全 测试技术
2025接口测试全攻略:高并发、安全防护与六大工具实战指南
本文探讨高并发稳定性验证、安全防护实战及六大工具(Postman、RunnerGo、Apipost、JMeter、SoapUI、Fiddler)选型指南,助力构建未来接口测试体系。接口测试旨在验证数据传输、参数合法性、错误处理能力及性能安全性,其重要性体现在早期发现问题、保障系统稳定和支撑持续集成。常用方法包括功能、性能、安全性及兼容性测试,典型场景涵盖前后端分离开发、第三方服务集成与数据一致性检查。选择合适的工具需综合考虑需求与团队协作等因素。
705 24