Day09 测试写起乃-FactoryBot(1)

在测试时常会需要建立假资料以供测试使用,就可以安装 FactoryBot 来建立资料

安装 FactoryBot

指令 gem "factory_bot_rails" 并且 bundle install

官方文件-FactoryBot Getting Started

基本语法就是使用 FactoryBot.create(:user) 就可以建立出一笔User了

可以在新增 spec/support/factory_bot.rb 并且把以下指令放在档案内,在 rspec 时就可以省略FactoryBot,直接 create(:user) 即可,那你也可以直接放在 rails_helper.rb 也同样有效。

#spec/support/factory_bot.rb or rails_helper.rb

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

建立第一笔资料

看文件只要将 file 依照以下位置摆放都会自动吃到

test/factories.rb
spec/factories.rb
test/factories/*.rb
spec/factories/*.rb

接下来新增一个 spec/factories/users.rb

# This will guess the User class
FactoryBot.define do
  factory :user do
    name { "CK" }
    email  { "[email protected]" }
  end
end

factory会从 class 去搜寻是否有 User 这个 class,没有的话他会提醒你他找不到,里头就可以直接填写 model 栏位右方 block 里面就是放内容。

我们到 console 试试是否能够建立出来吧!

# rails console -e test
2.6.6 :001 > FactoryBot.create(:user)
D, [2021-09-09T19:06:57.193940 #42363] DEBUG -- :    (1.7ms)  SELECT sqlite_version(*)
D, [2021-09-09T19:06:57.230186 #42363] DEBUG -- :   TRANSACTION (0.2ms)  begin transaction
D, [2021-09-09T19:06:57.231393 #42363] DEBUG -- :   User Exists? (0.6ms)  SELECT 1 AS one FROM "users" WHERE "users"."name" = ? LIMIT ?  [["name", "ck"], ["LIMIT", 1]]
D, [2021-09-09T19:06:57.234314 #42363] DEBUG -- :   User Create (0.8ms)  INSERT INTO "users" ("created_at", "updated_at", "name", "email") VALUES (?, ?, ?, ?)  [["created_at", "2021-09-09 11:06:57.231907"], ["updated_at", "2021-09-09 11:06:57.231907"], ["name", "ck"], ["email", "[email protected]"]]
D, [2021-09-09T19:06:57.235901 #42363] DEBUG -- :   TRANSACTION (0.9ms)  commit transaction
 => #<User id: 1, created_at: "2021-09-09 11:06:57.231907000 +0000", updated_at: "2021-09-09 11:06:57.231907000 +0000", name: "ck", email: "[email protected]", phone: nil>

所以就可以把原本的测试改写为

# user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'validations' do
    it { is_expected.to validate_presence_of(:name) }
  end

  describe 'count user' do
    let(:user) { create(:user) } # 此处使用factorybot 建立
    it 'no user' do
      expect(User.count).to eq(0)
    end

    it 'one user' do
      user
      expect(User.count).to eq(1)
    end
  end
end

但这边会遇到一个问题,如果我想一次建立两笔user但user名称又不能重复?

如果使用目前的user建立出来两笔资料 name 与 email 都会相同,该如何改呢?

sequence

# This will guess the User class
FactoryBot.define do
  factory :user do
    sequence(:name) { |n| "ck-#{n}"}
    sequence(:email) { |n| "ck-#{n}@gmail.com" }
  end
end
#rails console -e test
 => #<User id: 1, created_at: "2021-09-09 11:18:41.436395000 +0000", updated_at: "2021-09-09 11:18:41.436395000 +0000", name: "ck-1", email: "[email protected]", phone: nil>
=> #<User id: 2, created_at: "2021-09-09 11:19:17.282845000 +0000", updated_at: "2021-09-09 11:19:17.282845000 +0000", name: "ck-2", email: "[email protected]", phone: nil>

可以看到名称多编号这样一来就不会重复!

那你也可以使用 create_list(:factory_name,count) 一次建立两笔

#rails console -e test
2.6.6 :003 > FactoryBot.create_list(:user,2)
 => [#<User id: 3, created_at: "2021-09-09 11:20:10.871562000 +0000", updated_at: "2021-09-09 11:20:10.871562000 +0000", name: "ck-3", email: "[email protected]", phone: nil>,
 #<User id: 4, created_at: "2021-09-09 11:20:10.877319000 +0000", updated_at: "2021-09-09 11:20:10.877319000 +0000", name: "ck-4", email: "[email protected]", phone: nil>]

覆盖属性

在 factory 後方一样可以输入 attribute,覆盖掉原本预设的资料。

#rails console -e test
2.6.6 :005 > FactoryBot.create(:user, name:'ck_over',email: '[email protected]')
 => #<User id: 5, created_at: "2021-09-09 11:22:43.618214000 +0000", updated_at: "2021-09-09 11:22:43.618214000 +0000", name: "ck_over", email: "[email protected]", phone: nil>

基本上使用这些就可以解决大部分建立资料的问题,明天我们就可以来讲解,traitparentassociationalias


<<:  DevOps在MLOps当中的角色

>>:  switch-case 与select

[Day07]程序菜鸟自学C++资料结构演算法 – 链结串列实作应用

前言:讲解完链结串列的概念後,紧接着就要来进行实作了。 跟做阵列的时候一样,先创建一个新的专案,就可...

家齐高中资讯研究社 社课内容1

1.练习打字 在Typing Club练习打字 2.练习上传档案 3.下载及使用pyperclip模...

Windows 10 , 20H2 更新後 VPN无法连接

Windows 10 , 20H2 更新後 VPN无法连接 ,在此版本之前都使用正常,更新上去後无法...

Day 25-reverse terraform: terraformer,从 infrastructure 产生 .tf 内容

本篇介绍 terraformer,除了 import 既有的 remote resource 到 t...

Day16:今天来谈一下Microsoft Cloud App Security

Microsoft Cloud App Security是一种云端存取安全性代理人(CASB), 可...