Table of Contents
Rails の Helper に書いた current_user を使ったメソッドを RSpec でテストするときのやり方を書きます。
環境
- Ruby 2.2.2
- Rails 4.1.8
- RSpec 3.1.0
テスト対象
テストの対象となるメソッドは次のメソッドです。
gem devise で用意されている current_user と、 引数で渡された user_id を比較して、 ログインしているユーザなのか否かを判定しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module ExampleHelper # check if the id is of current user # ==== Parameter # * +user_id+ # ==== Return # Boolean def is_current_user?(user_id) if current_user && current_user.id == user_id return true end return false end end |
エラーの出るテストコード
次のコードはエラーが出ます、 単純にメソッドを呼んでいるだけで特別なことはしていないのですが。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
require 'rails_helper' describe ExampleHelper, type: :helper do let(:user) { create(:user) } describe '#is_current_user?(user_id)' do describe 'on logging in' do it 'returns true' do expect(helper.is_current_user?(user.id)).to be(true) end end end end |
問題点
- Helper 内 で使用される
current_userがundefined methodになってしまう。
Helper を View 内 で使用する場合は エラーなく実行できるのですが、 RSpec のテストとなると undefined method になってしまいます。
Devise::TestHelper を読み込んでもエラーが出ます。 current_user が使用する @current_user を直接変更してもエラーが出ます (undefined method なので @current_user にも到達できません) 。
通るテストコード
次のように、 stub を利用してテストを通します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
require 'rails_helper' describe ExampleHelper, type: :helper do let(:user) { create(:user) } describe '#is_current_user?(user_id)' do describe 'on logging in' do it 'returns true' do allow(helper).to receive(:current_user).and_return(user) expect(helper.is_current_user?(user.id)).to be(true) end end end end |
stub を利用して helper の current_user が呼ばれたときに user を返すようにしています。
Stub の書き方に注意
Stub を helper.stub(:current_user).and_return(true) のようにして作成すると RSpec 3.3 では WARNING が表示されます。 そのような書き方は 現在では非推奨になっているため、次のメッセージが表示されます。
Using stub from rspec-mocks’ old :should syntax without explicitly enabling the syntax is deprecated. Use the new :expect syntax or explicitly enable :should instead.



