iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

Rails測試寫起乃!!!系列 第 6

Day06 測試寫起乃 - before、after

before 用法比較像是在測試之前你需要哪些前置作業? after 就是在測試之後要做哪些事情? 由於 after 比較少使用我們就先以 before 為主,我們先看以下超簡單的範例

before

# user.rb
  def change_name(new_name)
    return false if new_name.blank?

    self.name = new_name
    save!
  end
end
#user_spec.rb
describe '#change_name' do
  it 'will change the name' do
    @user = User.create!(name: 'test')
    @user.change_name('new_name')
    expect(@user.name).to eq('new_name')
  end

  it 'will not change name' do
    @user = User.create!(name: 'test')
    @user.change_name('')
    expect(@user.change_name('')).to eq(false)
  end
  end

如果用 before 修改可以寫成以下,預設為before(:each)

#user_spec.rb
describe '#change_name' do
    before do
      p '這是before'
      @user = User.create!(name: 'test')
    end

    it 'will change the name' do
      @user.change_name('new_name')
      expect(@user.name).to eq('new_name')
    end

    it 'return false if name is blank' do
      expect(@user.change_name('')).to eq(false)
    end
  end

這麼做的好處就是可以將一些 it 會重複使用到的 code 放到 before 裡節省 code

但仔細看會發現如果是使用 before(:each) 的話在執行兩個 it 前會進去 before

$ rspec spec/models/user_spec.rb
.."這是before"
."這是before"
.

Finished in 0.13856 seconds (files took 3.94 seconds to load)
4 examples, 0 failures

如果是before(:all)呢?

rspec spec/models/user_spec.rb
.."這是before"
..

Finished in 0.11651 seconds (files took 3.64 seconds to load)
4 examples, 0 failures

只會進去一次!所以說

before(:each) => 在每個 it 之前執行
beofore(:all) => 在每個 describe 之前執行
beofore(:suite) => 在每個測試檔之前執行(很少用到就不舉例了)

有更多 before 用法可以在 before-and-after-hooks 查到

想知道每個 before 先後排序可以看這篇
in-rspec-whats-the-difference-between-beforesuite-and-beforeal

after

after 個人最常用來在解除 TimeCop.freeze(),有些測試會去針對時程上或是訊息含有時間時就會推薦先將測試前指定時間點並在after 復原。這樣一來整個區間內都會在 Timecop 指定的時間中。

RSpec.describe User, type: :model do
  before(:all) do
    Timecop.freeze(Time.current)
  end

  after(:all) do
    Timecop.return
  end
  
  describe '#change_name' do
    before do
      p '這是before'
      @user = User.create!(name: 'test')
    end

    it 'will change the name' do
      @user.change_name('new_name')
      expect(@user.name).to eq('new_name')
    end

    it 'return false if name is blank' do
      expect(@user.change_name('')).to eq(false)
    end
  end
end

因為有一些
明天就可以來說明 letlet!subject摟!


上一篇
Day05 測試寫起乃 - Shoulda Matchers
下一篇
Day07 測試寫起乃- let、let!、subject
系列文
Rails測試寫起乃!!!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言