Table of Contents
I’ll introduce the way to test rails helper code that uses current_user
method provided by device gem.
Environment
- Ruby 2.2.2
- Rails 4.1.8
- RSpec 3.1.0
Test Target
The function we are going to test is below. It compare the return value of current_user
method and user_id
given as argument, and check the argument user_id
is of current login user or not.
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 |
Bad Test Code
The following code raise error. Of course, it simply call a method.
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 |
Problem
- The method
current_user
used in Helper isn’t usable. It’s handled as undefined method.
We can use helper in View component without error, but in test code we can’t. current_user
is undefined method.
It can’t be solved by including Devise::TestHelper
, or using @current_user
directly that is used by current_user
method. (Undefined method current_user
can’t reach @current_user
) .
Good Test Code
Like the following code, use stub in the test code.
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 |
Using stub feature, helper
returns user
when it’s current_user
method is called.
Attention to Stub Generation
If you generate Stub like helper.stub(:current_user).and_return(true)
, RSpec 3.3 prints WARNING below. It’s old style and deprecated.
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.