just so
just so

Reputation: 1138

Testing current user in helper spec

I have this pretty basic helper which relies on current_user variable provided by Sorcery in controllers and helpers

def current_user_link
    user_link current_user
end

 def user_link(user, html_options = {}, &block)
   link_to user.to_s, user, html_options, &block
 end

How can I test this helper?

describe UsersHelper do
  describe '#current_user_link' do
    it 'should return a link to the current user' do
      expected_link = link_to current_user.name, current_user
      ???

      expect(current_user_link).to eq expected_link
    end
  end

Do I need to stub current_user somehow? Is it even worth testing?

Upvotes: 7

Views: 5781

Answers (7)

Fábio Araújo
Fábio Araújo

Reputation: 495

For those who came from Devise:

You can simply define the method inside the spec.

  describe 'option_for_product_weight' do
    before {
      def helper.current_user
        User.first
      end
    }

    subject { helper.option_for_product_weight }

    it 'returns the list' do
      expect(subject).not_to be_empty
    end
  end

Upvotes: 0

vanboom
vanboom

Reputation: 1332

When testing helper modules with RSpec, you need to stub the method in your Rspec::ExampleGroups target...

    allow_any_instance_of(RSpec::ExampleGroups::UsersHelper).to receive(:current_user).and_return user

Upvotes: 0

ChooseN
ChooseN

Reputation: 79

simpliest work around is to declare in spec:

let(:current_user) { create(:user) }

Upvotes: 4

Abel Pc Ag
Abel Pc Ag

Reputation: 96

This worked for me:

describe UsersHelper do
  describe '#current_user_link' do
    it 'should return a link to the current user' do
      user = FactoryGirl.create(:user)
      allow_any_instance_of(UsersHelper).to receive(:current_user).and_return(user)

      expected_link = link_to user.name, user
      expect(current_user_link).to eq(expected_link)
    end
  end
end

In the rails_helper.rb you need to have:

RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :helper
end

Upvotes: 0

Eric Marchese
Eric Marchese

Reputation: 404

I was trying to use current_user with Sorcery in an Rspec ApplicationHelper spec and none of the above answers worked for me.

What worked for me was first defining a user with FactoryGirl:

let(:user) { create(:user) }

Then, write an example like this:

it "does stuff" do
  allow(helper).to receive(:current_user).and_return(user)
  expect(helper.some_method_using_current_user).to do_something
end

Key difference is using the helper object in the example.

Upvotes: 6

Oleh  Sobchuk
Oleh Sobchuk

Reputation: 3722

you can stub your current_user

describe UsersHelper do
  describe '#current_user_link' do
    let(:user) { FactoryGirl.build(:user) }
    let(:expected_link) { link_to user.name, user }

    before { allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) }

    it { expect(current_user_link).to eq(expected_link) }
  end
end

or set your user to session than you should

let(:user) { FactoryGirl.create(:user) }

and

before { allow_any_instance_of(ActionDispatch::Request).to receive(:session).and_return(user_id: user.id) }

Upvotes: 2

just so
just so

Reputation: 1138

This is how I solved it.

describe '#current_user_link' do
  it 'returns a link to the current user ' do
    user = build(:user)
    expected_link = link_to user.name, user
    allow(controller).to receive(:current_user).and_return(user)

    expect(helper.current_user_link).to eq(expected_link)
  end
end

PSA: dont forget to call your method on helper.

Upvotes: 7

Related Questions