Everyday-rails-rspec - 预构件和固件

固件:Rails 默认提供了快速生成示例数据的工具,叫做“固件”。
固件是一个yaml格式的文件,可以用来生成示例数据。
例如下面是一个Contactmodel的固件:

# contact.yml
aaron: 
  firstname: "Aaron" 
  lastname: "Sumner" 
  email: "[email protected]"
john: 
  firstname: "John" 
  lastname: "Doe" 
  email: "[email protected]"

在测试中,我们使用contact(:aaron),就会得到一个联系人。

固件有两个问题我是极力避免的:

  • 固件中的数据很容易被破坏(这意味着要花费与编写测试和应用代码相等的时间维护测试数据);
  • Rails 在把固件中的数据存入“测试数据库”时会跳过 Active Record层。这意味着很多重要的操作,例如模型的数据验证,会被忽略。这样可不好。

预构件:简单灵活地创建测试数据。Factory Girl这个工具不像固件那么容易破坏,方便使用,生成的测试数据也很可靠。
缺点

  • 会降低测试速度

在应用中使用预构件

在spec文件夹下创建factories/contacts.rb并写入下面的代码

FactoryGirl.define do
    factory :contact do
        firstname "John"
        lastname "Doe"
        sequence(:email) { |n| "johndoe#{n}@example.com"}
    end
end

** sequence是FactoryGirl提供的一个功能,每调用一次,n的值都会+1**

*** 只要模型中有唯一性验证,都可以使用sequence(序列)***

测试代码:

require 'rails_helper'

describe Contact do  
  it 'has a valid build' do 
    expect(FactoryGirl.build(:contact)).to be_valid
  end  
  it 'is invalid without a firstname' do
    contact = FactoryGirl.build(:contact, firstname: nil)                       contact.valid?
    expect(contact.errors[:firstname]).to include("can't be blank")  
  end    

  it 'is invalid with a duplicate email address' do    
    FactoryGirl.create(:contact, email: '[email protected]')  
    contact = FactoryGirl.build(:contact,email:'[email protected]')
    contact.valid?     
    expect(contact.errors[:email]).to include("has already been taken")
  end
end

*** FactoryGirl.build 的 作 用 是 在 内 存 中 存 储 一 个 新 测 试 对 象;FactoryGirl.create 的作用是把对象永久存储到应用的测试数据库中。***

生成更真实的虚拟数据-Faker

这里我们介绍一个虚拟数据生成工具Faker.
使用Faker之后我们的factories的代码就变成了下面的样纸。它会生成看起来更真实的测试数据

FactoryGirl.define do
    factory :contact do
       firstname { Faker::Name.first_name } 
       lastname { Faker::Name.last_name } 
       email { Faker::Internet.email }
    end
end

你可能感兴趣的:(Everyday-rails-rspec - 预构件和固件)