我们正在尝试测试我们的控制器根据我们的param调用一个给定次数的类,但我们的测试在rspec中失败,说我们类的initialize方法返回nil。
我们有这个控制器:
class ProcessFaxesController < ApplicationController
def create
email = params["From"]
attachment_count = params["attachment-count"].to_i
head :ok
if attachment_count > 0
attachment_count.times do |document_index|
FaxedDocumentProcessor.new(params, document_index+1).perform
end
else
DocumentProcessingMailer.delay.failure_notification(email, "No attachment found.")
end
end
end
外部课程:
class FaxedDocumentProcessor
def initialize(params, document_index)
@params = params
@attachment = @params["attachment-#{document_index}"]
@email = @params['From']
end
def perform
# some stuff here
end
end
使用此规范:
require 'rails_helper'
RSpec.describe ProcessFaxesController, type: :controller do
context "#create" do
context 'with attachments' do
before { allow_any_instance_of(FaxedDocumentProcessor).to receive(:perform).and_return(true) }
it 'calls the FaxedDocumentProcessor attachment-count times' do
expect(FaxedDocumentProcessor).to receive(:new).twice
post :create, 'email' => 'test@example.com', 'attachment-count' => 2)
end
end
end
end
这是我们从测试中得到的错误:
Failures:
1) ProcessFaxesController#create with attachments calls the FaxedDocumentProcessor attachment-count times
Failure/Error: FaxedDocumentProcessor.new(params, document_index+1).perform
NoMethodError:
undefined method `perform' for nil:NilClass
# ./app/controllers/process_faxes_controller.rb:20:in `block in create'
# ./app/controllers/process_faxes_controller.rb:19:in `times'
# ./app/controllers/process_faxes_controller.rb:19:in `create'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/abstract_controller/base.rb:198:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/metal/rendering.rb:10:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/callbacks.rb:117:in `call'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/callbacks.rb:505:in `call'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/callbacks.rb:92:in `__run_callbacks__'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/callbacks.rb:81:in `run_callbacks'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/abstract_controller/callbacks.rb:19:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/metal/rescue.rb:29:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/notifications.rb:164:in `block in instrument'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activesupport-4.2.6/lib/active_support/notifications.rb:164:in `instrument'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/activerecord-4.2.6/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/abstract_controller/base.rb:137:in `process'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionview-4.2.6/lib/action_view/rendering.rb:30:in `process'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/test_case.rb:639:in `process'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/test_case.rb:67:in `process'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/devise-3.5.6/lib/devise/test_helpers.rb:19:in `block in process'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/devise-3.5.6/lib/devise/test_helpers.rb:72:in `catch'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/devise-3.5.6/lib/devise/test_helpers.rb:72:in `_catch_warden'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/devise-3.5.6/lib/devise/test_helpers.rb:19:in `process'
# /Users/mary/.rvm/gems/ruby-2.3.0@website/gems/actionpack-4.2.6/lib/action_controller/test_case.rb:520:in `post'
# ./spec/controllers/process_faxes_controller_spec.rb:22:in `block (4 levels) in <top (required)>'
我们已经尝试将binding.pry
插入到控制器方法中以便自我调整,但每当我们尝试正在爆炸的调用时,我们都不会出现任何错误。
可能导致FaxedDocumentProcessor.new
返回零的原因是什么?为什么我们不能在pry中重现错误?
答案 0 :(得分:15)
这是由于:
造成的expect(FaxedDocumentProcessor).to receive(:new).twice
上面的行完全存根new
方法。要使其调用原始方法,请执行:
expect(FaxedDocumentProcessor).to receive(:new).twice.and_call_original