RSpec-Rails當中自訂methods及helpers
在RSpec當中,常常會有些瑣碎的東西需要重複輸入,尤其是unit test,如果能夠包成helper methods,在不同檔案間重複利用,是再好不過的事情。以下提供兩個簡便的方法,可以撰寫專門給RSpec使用的methods,不會被Rails app本身觸發到。
1. 定義為Module
最快也最簡便的方法,就是在rails_helper.rb
或spec_helper.rb
裡面定義這些methods,這樣就不用在每一個RSpec檔案當中重新載入(畢竟每次都要require 'rails_helper'
就已經夠煩了)。
例如要測試model之間的關係,我們會在測試當中這樣寫:
require 'rails_helper'
RSpe.describe User, :type => :model do
it "has_many posts" do
association = User.reflect_on_association(:post)
expect(association.macro).to eq(:has_many)
end
end
當然,只要稍微複雜一點的網站或應用程式,這樣的敘述就會變得非常冗長。假如我們在一個model當中寫了20個這樣的測試,其實對可讀性來說非常沒有幫助。這時,可以把這個method包含到helper中,寫成這樣:
module CustomHelpers
def expect_relation(model, relation, target)
association = model.reflect_on_association(target)
expect(association.macro).to eq(relation)
end
end
包好之後,再重新調整原本的寫法:
RSpe.describe User, :type => :model do
it { expect_relation(User, :has_many, :posts)}
end
原本長得要命的兩句話,縮減成簡易又好懂的一句話,這樣就算連續測試10個以上的model relation,code也會乾淨簡潔。
要將helpers納入測試當中,要進入rails_helper.rb
或spec_helper.rb
當中添加,筆者個人比較傾向於前者。接著在最前面幾行加上:
require './spec/custom_helpers'
# 檔名端看如何命名,個人會命名為cusom_helpers.rb
接著在下方的RSpec設定當中添加:
RSpec.configure do |config|
config.include CsutomHelpers
# 僅添加此行即可
end
就可以順利在測試中使用該module內包含的methods。
當然,這個方法在官方文件上也有非常詳細的說明。
2. 定義為shared_context
如果用module的方式,那每一個測試都會自動載入該module。假如我們不希望每次都載入該module呢?這時就可以使用shared_context
來指定要使用的helpers,sharedcontext的方法稍嫌囉嗦,但如果有特定method只希望其中幾個測試可以使用,那包在sharedcontext當中可以較為精確。
首先在spec
資料夾底下開一個contexts
資料夾,裡面建立一個helpers.rb
檔案。
RSpec.shared_context "custom_helpers" do
def my_helpers
# ...
end
end
定義完成以後,shared_context運作的方式是需要在每個測試當中將context指定納入,才會可以使用,以確保只有在需要用的時候再呼叫這些methods。以剛剛的User
model為例,寫法變成:
require './spec/contexts/custom_helpers'
RSpe.describe User, :type => :model do
include_context "custom_helpers"
# 開始用helper寫code
end
除了讀取檔案之外,也要特別指定include_context
才行。如果require
檔案嫌麻煩,也可以整理到rails_helper
檔案當中,這樣就不需要每次都特別require
進來。
官方文件也有詳細說明Shared Context要如何使用。