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

Controller test with RSPEC error does not implement

我正在尝试用 RSPEC 测试我的 API 控制器。控制器中的操作有一个我想要的服务 stub/mock。但是我得到了错误:

Failure/Error: expect(Api::V1::PaymentsController).to receive(:init_alias).and_return(svc) Api::V1::PaymentsController does not implement: 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

控制器:

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

编辑:

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

Failure/Error: expect(svc).to receive(:insert) (InstanceDouble(AliasService) (anonymous)).insert(*(any args)) expected: 1 time with any arguments received: 0 times with any arguments

控制器方法是实例方法。因此,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)

编辑

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

你可以这样做:

let(:alias_svc) { instance_double(AliasService) }
controller.instance_variable_set(:@svc, alias_svc)

More details