目次
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.