@therhino

Как протестировать модуль?

Есть модуль authenticable.rb:
module Authenticable
	
	def current_user
		@current_user ||= User.find_by(auth_token: request.headers['Authorization'])
	end

	def authenticate_with_token!
		render json: { errors: "Not authenticated" },
								status: :unauthorized unless user_signed_in?
	end

	def user_signed_in?
		current_user.present?
	end

end


В своем коде я его использую для предотвращения несанкционированного доступа, примерно так:
# app/controllers/api/v1/appication_controller.rb
class Api::V1::ApplicationController < ActionController::Base
  protect_from_forgery with: :null_session

  include Authenticable
end

# app/controllers/api/v1/users_controller.rb
class Api::V1::UsersController < Api::V1::ApplicationController
	respond_to :json
	before_filter :authenticate_with_token!, only: [:update, :destroy]
....
.....
end


Есть тест authenticable_spec.rb:
require 'rails_helper'

class Authentication < ActionController::Base
  include Authenticable
end

describe Authenticable do
  let(:authentication) { Authentication.new }
  subject { authentication }

  describe "#authenticate_with_token" do
    before do
      authentication.stub(:current_user).and_return(nil)
      ??????
    end

    it "render a json error message" do
      expect(json_response[:errors]).to eql "Not authenticated"
    end

  	it { response.status.should eq 401 }
  end


Что мне нужно написать вместо ??????, чтобы тесты работали?
  • Вопрос задан
  • 2478 просмотров
Решения вопроса 1
Jeiwan
@Jeiwan
describe '.authenticate_with_token' do
  before do
    allow(authentication).to receive(:current_user).and_return(nil)
    allow(authentication).to receive(:render) do |args| # возвращаем аргументы
      args
    end
  end

  it 'returns error' do
    expect(authentication.authenticate_with_token![:json][:errors]).to eq 'Not authenticated'
  end

  it 'returns unauthorized status' do
    expect(authentication.authenticate_with_token![:status]).to eq :unauthorized
  end
end


Ваша ошибка в том, что вы думаете, что тестируете контроллер. На самом деле, контроллер здесь нужно только для того, чтобы было можно протестировать методы модуля (для инклуда модуля можно даже взять голый класс). И метод response тут будет недоступен, так как мы тестируем модуль, а не контроллер.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@therhino Автор вопроса
Когда использовать голый клас
class Authentication
  include Authenticable
end

то вылетает ошибка
Authenticable.authenticate_with_token returns error
     Failure/Error: allow(authentication).to receive(:render) do |args|
       #<Authentication:0xb982078> does not implement: render

Получается allow позволяет мокать только существующие методы?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы