Rspec 测试:对接受来自另一台服务器的 api 请求的控制器的覆盖率不工作

问题描述

尝试为接受来自其他服务器/服务的 api 请求的控制器编写 Rspec 测试。

下面的代码以/servers/users/some/create(发布请求)的形式接受从另一个服务发起的请求,以供经过身份验证的用户使用

    module Servers
      module Users
        class SomeController < ::Servers::Users::BaseController
    
          def create
            some_service.create!
            render json: {status: 'ok'}
          end
         end

         def some_service
          if current_user.randommodel.nil?
           @some_service ||= ::SomeService.new(current_user)
         end

randommodel 嵌入在用户类中,认情况下不存在。 Some_Service 负责创建这个随机模型

class SetupMfaService
  attr_accessor :current_user

  def initialize(current_user)
   @current_user = current_user
  end

 def create! 
  current_user.randommodel = randommodel.new
  current_user.randommodel.save!
 end

此服务类已完全覆盖测试并按预期工作

SomeService 已经完全被测试覆盖并且运行良好。 (有用)。但是,当我尝试通过执行以下操作来测试此方法时:

require 'rails_helper'
require 'requests/servers/servers_api_context'

RSpec.describe '::Servers::Users::SomeController' do
  include_context "Servers API"

  let!(:user) { Fabricate(:user,{ clear_password: password }) }
  let(:request_auth_data) do
    {
      user_id: user.id,account_id: user.account_id,role: ''
    }
  end

  let(:source_server) { 'web_application' }
  let(:endpoint) { 'localhost' }


  context 'create' do
    subject do
      servers_api_post '/servers/users/some/create'
    end

    it 'returns a 200' do
      response = subject
      expect(response.status).to be(200)
    end

    it 'returns the expected JSON data' do
      response = subject
      expect(response.data).to eql({})
    end

  end
end

测试失败,没有方法错误 'somemodel' for nil:NilClass 这对我来说意味着它无法检测 current_user 的存在(它在我的控制器继承自 attr_reader :current_user 的基本控制器中可用. 还有一个 decoded_pa​​yload 对象,它允许我们读取处理的请求中存在的参数,其中包含我试图在下面的控制器中查找的用户 ID,尽管这个过程是在 BaseController 中完成的此控制器也继承自。这使我得出结论,我编写测试的方式是错误的。如何在此控制器文件的 rspec 测试中显式显示当前用户参数?~

请求的登录在 BaseController 中处理,并继承到我的 SomeController 中

  def authenticate
    @jwt = case request_source
           when 'web_application'
             ::Servers::WebApplication::JwtAuthService.new(endpoint).decrypt_and_verify(jwe)

           else
             raise 'UnkNown request source'
           end

    @current_user = User.find(decoded_payload[:user_id])
    @current_account = current_user&.account
    raise ::Api::Error::AccountNotFound.new if current_account.blank?
  end

解决方法

假设 somemodel 您的意思是 current_user.randommodel.nil?,那么您的测试未登录。测试声明 request_auth_data 但似乎没有对它做任何事情。

我无法告诉您如何登录,只是您的测试必须这样做。

您的测试也揭示了控制器中的错误。如果需要登录,API 应该响应 401 Unauthorized,而不是异常。通常这是通过从需要并处理授权的控制器基类继承来处理的。