2017-06-29 60 views
1

我想用RSPEC测试我的API控制器。控制器中的操作具有我想要存根/模拟的服务。但我得到了错误:RSPEC错误的控制器测试不执行

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接收(: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

回答

2

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

+0

它几乎可以工作,谢谢。但我仍然有第二个错误 – Xero

+0

将'alias_svc'传递给'instance_variable_set'。我已经更新了答案。 – yzalavin