ironsand
ironsand

Reputation: 15171

undefined method `header` in RSpec

To learn API by using Rails I'm reading this tutorial.

In a part of RSpec test there is a method like this:

spec/support/authentication_helper.rb

module AuthenticationHelper
  def sign_in(user)
    header('Authorization', "Token token=\"#{user.authentication_token}\", email=\"#{user.email}\"")
  end
  def create_and_sign_in_user
    user = FactoryGirl.create(:user)
    sign_in(user)
    user
  end
  alias_method :create_and_sign_in_another_user, :create_and_sign_in_user
end

RSpec.configure do |config|
  config.include AuthenticationHelper, type: :api
end

And the test failed by undefined method `header'.

Where is this header method defined?

This is the whole source code of this tutorial. https://github.com/vasilakisfil/rails_tutorial_api/

spec/apis/users_spec.rb

require 'rails_helper'

describe Api::V1::UsersController, type: :api do
  context :show do
    before do
      create_and_sign_in_user
      @user = FactoryGirl.create(:user)

      get api_v1_user_path(@user.id), format: :json
    end

    it 'returns the correct status' do
      expect(last_response.status).to eql(200)
    end

    it 'returns the data in the body' do
      body = HashWithIndifferentAccess.new(MultiJson.load(last_response.body))
      expect(body[:user][:name]).to eql(@user.name)
      expect(body[:user][:updated_at]).to eql(@user.updated_at.iso8601)
    end
  end
end

StackTrace

  1) Api::V1::UsersController show returns the correct status
     Failure/Error: create_and_sign_in_user
     NameError:
       undefined local variable or method `request' for #<RSpec::ExampleGroups::ApiV1UsersController::Show:0x007fcbfec91d60>
     # ./spec/support/authentication_helper.rb:4:in `sign_in'
     # ./spec/support/authentication_helper.rb:9:in `create_and_sign_in_user'
     # ./spec/apis/user_spec.rb:6:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:39:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:38:in `block (2 levels) in <top (required)>'
     # -e:1:in `<main>'

  2) Api::V1::UsersController show returns the data in the body
     Failure/Error: create_and_sign_in_user
     NameError:
       undefined local variable or method `request' for #<RSpec::ExampleGroups::ApiV1UsersController::Show:0x007fcbfb7cfa28>
     # ./spec/support/authentication_helper.rb:4:in `sign_in'
     # ./spec/support/authentication_helper.rb:9:in `create_and_sign_in_user'
     # ./spec/apis/user_spec.rb:6:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:39:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:38:in `block (2 levels) in <top (required)>'
     # -e:1:in `<main>'

Upvotes: 1

Views: 3680

Answers (2)

ironsand
ironsand

Reputation: 15171

I had to add api_helper.rb to use the methods.

module ApiHelper
  include Rack::Test::Methods

  def app
    Rails.application
  end
end

RSpec.configure do |config|
  config.include ApiHelper, type: :api #apply to all spec for apis folder
  config.include Rails.application.routes.url_helpers, type: :api
end

Here is source code in Github. https://github.com/vasilakisfil/rails_tutorial_api/blob/008af67e88897a5bcde714ce13d39a26ec70fba7/spec/support/api_helper.rb

Upvotes: 1

Kern Cheh
Kern Cheh

Reputation: 775

In spec/support/auth_helpers.rb, you can try something like this

module AuthHelpers
  def authenticate_with_user(user)
    request.headers['Authorization'] = "Token token=#{user.token}, email=#{user.email}"
  end

  def clear_authentication_token
    request.headers['Authorization'] = nil
  end     
end

In Rspec's spec/rails_helper.rb

Rspec.configure do |config|
  config.include AuthHelpers, file_path: /spec\/apis/
end

An example test in spec/apis/users_controller_spec.rb:

require 'rails_helper'

describe Api::V1::UsersController, type: :controller do
  let(:user) { create(:user) }

  context 'signed in' do
    before do
      authenticate_with_user user
    end

    it 'does something' # tests here
  end
end

Hope it helps!

Edit: Note the type: :controller is important

Upvotes: 0

Related Questions