繁体   English   中英

在RSpec请求中存根方法调用的正确方法

[英]Correct way of stubbing method call in RSpec request

我正在尝试在我的请求规范中存根:authenticate_user方法调用,以便测试用户的关联创建。 我将这些博客文章用作存根的指南:

1) https://8thlight.com/blog/mike-knepper/2014/07/01/stubbing-authentication-and-authorization-in-controller-specs.html

2) http://johnnyji.me/rspec/2015/06/18/stubbing-controller-instance-methods-in-rspec.html

我在存根上没有任何成功,也弄不清我缺少什么。

当我尝试

it 'creates a new contract' do
      allow(controller).to receive(:authenticate_user).and_return(user)
      post api_v1_user_contracts_path(user), { params: contract_params}
      expect(response).to have_http_status(200)
    end

我有: 在此处输入图片说明

当我尝试:

it 'creates a new contract' do
      allow_any_instance_of(controller).to receive(:authenticate_user).and_return(user)
      post api_v1_user_contracts_path(user), { params: contract_params}
      expect(response).to have_http_status(200)
    end

我有 在此处输入图片说明

我的代码:spec / requests / contracts_api_spec.rb

require 'rails_helper'
require 'pry'
context "POST #create" do
    let (:user) { User.create(full_name: "Jason Bourne", email: "jbourne@test.com", password: "123456") }
    let (:contract_params) do
      {
        "contract[vendor]" => "Lebara",
        "contract[starts_on]" => "2018-12-12",
        "contract[ends_on]" => "2018-12-16",
        "contract[price]" => "15"
      }
    end

    it 'creates a new contract' do
      allow(controller).to receive(:authenticate_user).and_return(user)

      post api_v1_user_contracts_path(user), { params: contract_params}
      expect(response).to have_http_status(200)
    end

应用程序/控制器/ API / V1 / contracts_controller.rb

class Api::V1::ContractsController < ApplicationController
  before_action :authenticate_user

  def show
    if @current_user.contracts.find_by(id: params[:id])
      render json: @current_user.contracts.find_by(id: params[:id])
    else
      render json: { error: "Contract not found"}, status: 400
    end
  end

  def create
    contract = @current_user.contracts.build(contract_params)
    if contract.save
      render json: contract
    else
      render json: { error: contract.errors }, status: 400
    end
  end

应用程序/控制器/关切/ token_authenticatable.rb

class NotAuthorizedException < StandardError; end

module TokenAuthenticatable
  extend ActiveSupport::Concern

  included do
    attr_reader :current_user

    before_action :authenticate_user

    rescue_from NotAuthorizedException, with: -> { render json: { error: 'Not Authorized' }, status: :unauthorized }
  end

  private

  def authenticate_user
    @current_user = DecodeAuthenticationCommand.call(request.headers).result
    raise NotAuthorizedException unless @current_user
  end
end

其他问题:

1)我应该使用真实的User对象,还是应该使用double对象? 我假设它应该是真实用户,以便测试关联创建是否正常。

2)我应该使用allow( Api :: V1 :: ContractsController )。来接收(:authenticate_user).and_return(user)吗? 我曾经尝试过,但是没有用,但我不知道这是因为其他原因也破坏了它。

感谢您提供的任何反馈!

关键是authenticate_user将用户分配给变量(稍后使用)。 请试试:

allow(DecodeAuthenticationCommand).to receive_message_chain(:call, :result).and_return(user)

使用双重测试,您将必须为用户定义所有方法,例如contracts 另外,您正在检查合同是否已创建-在我看来,为user使用真实对象是完全可以的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM