带有RSPEC错误的控制器测试未实现

Xer*_*ero 4 ruby rspec ruby-on-rails mocking rspec-rails

我正在尝试使用RSPEC测试我的API控制器。控制器中的动作有一个我想存根/模拟的服务。但是我得到了错误:

失败/错误:期望(Api :: V1 :: PaymentsController)。接收(:init_alias).and_return(svc)Api :: V1 :: PaymentsController未实现:init_alias

这是我的测试:

  let(:alias_svc) { instance_double(AliasService) }

  describe 'POST /payment/card' do
    it 'returns urls (return, success, fail)' do
      expect(Api::V1::PaymentsController).to receive(:init_alias).and_return(alias_svc)
      expect(alias_svc).to receive(:insert)

      post '/payment/card'
    end
  end
Run Code Online (Sandbox Code Playgroud)

和控制器:

module Api
  module V1
    class PaymentsController < ApiController
      before_action :init_alias, only: [:register_card]

      # POST /payment/card
      def register_card
          @url = @svc.insert current_user
      end

      private
      def init_alias
        @svc = AliasService.new
      end

    end
  end
end
Run Code Online (Sandbox Code Playgroud)

编辑:

我试图删除第一行(expect(Api :: V1 :: PaymentsController).to receive(:init_alias).and_return(alias_svc))但我得到了

失败/错误:期望(svc).to接收(:insert)(InstanceDouble(AliasService)(匿名))。insert(*(任何参数))预期:收到任何参数的次数为1:收到任何参数的次数为0

yza*_*vin 5

控制器方法是实例方法。因此,Api::V1::PaymentsController不执行init_alias

RSpec允许使用expect_any_instance_of

expect_any_instance_of(Api::V1::PaymentsController).to receive(:init_alias).and_return(alias_svc)
Run Code Online (Sandbox Code Playgroud)

编辑

您将消息发送到@svc。因此,您应该将此实例变量模拟到您的控制器。

您可以执行以下操作:

let(:alias_svc) { instance_double(AliasService) }
controller.instance_variable_set(:@svc, alias_svc)
Run Code Online (Sandbox Code Playgroud)

更多细节