在使用RSpec进行测试时,如何正确捕获Sidekiq worker中的错误?

在使用RSpec进行测试时,如何正确捕获Sidekiq worker中的错误?,rspec,sidekiq,webmock,excon,Rspec,Sidekiq,Webmock,Excon,我有一个相对简单的工人,他使用Excon从互联网上获取一些东西。我试图成为一名优秀的测试人员,并使用Webmock强制对internet交互进行存根,因此我实际上是在测试基于各种存根交互的代码应该做什么 我注意到RSpec没有捕捉到发生在工人内部的故障。这可能是我的代码,可能是个bug,我不确定 下面是一个简单的工作者示例(是的,我知道营救异常很糟糕,我将在下一步修复它): include Sidekiq::Worker sidekiq_选项队列:“获取文章内容”,重试:true,回溯:true

我有一个相对简单的工人,他使用Excon从互联网上获取一些东西。我试图成为一名优秀的测试人员,并使用Webmock强制对internet交互进行存根,因此我实际上是在测试基于各种存根交互的代码应该做什么

我注意到RSpec没有捕捉到发生在工人内部的故障。这可能是我的代码,可能是个bug,我不确定

下面是一个简单的工作者示例(是的,我知道营救异常很糟糕,我将在下一步修复它):

include Sidekiq::Worker
sidekiq_选项队列:“获取文章内容”,重试:true,回溯:true
def执行(url)
开始
获取(url)
救援异常=>e
warn(“错误:{e}”)
无
结束
结束
结束
下面是一个简化的RSpec测试:

Sidekiq::Testing.inline!
work=FetchArticleContentWorker.new
工作。执行(”http://google.com")
启用Webmock后,这将导致Excon失败(见test.log文件):

然而,RSpec认为这很有效:

.

Finished in 0.44487 seconds (files took 5.35 seconds to load)
1 example, 0 failures
我不确定我做错了什么。我认为Sidekiq
perform
未能作为一个失败被发送到RSpec,但事实并非如此

  • 我没有正确地捕捉到这个错误吗
  • 我是否应该检查与作业状态相关的内容,而不是期望RSpec在worker中捕获此错误
  • 我应该完全做别的事情吗

谢谢

我认为从rspec的角度来看,没有错误,因为它是在worker内部捕获/处理的。如果你取消了救援,我预计测试会失败,正如你所预料的那样。相反,您可以在测试中检查perform是否返回非nil值以通过测试。这有帮助吗?

为了让RSpec看到异常,代码必须引发异常

您可以重新引发现有异常:

def perform(url)
  begin
    Excon.get(url)
  rescue Exception => e
    Rails.logger.warn("error: #{e}")
    raise e
  end
end
您可以将现有异常包装到您自己的异常中:

class MyFancyException < StandardError; end

def perform(url)
  begin
    Excon.get(url)
  rescue Exception => e
    Rails.logger.warn("error: #{e}")
    raise MyFancyException.new(e)
  end
end
class MyFancyException < StandardError; end

def perform(url)
  begin
    Excon.get(url)
  rescue Exception => e
    Rails.logger.warn("error: #{e}")
    raise MyFancyException.new(e)
  end
end
describe Worker do
  subject(:worker) { described_class.new }

  describe "#perform" do
    subject(:perform) { worker.perform }

    let(:url) { "https://google.com" }

    it "raises exception" do
      expect { perform(url) }.to raise_error(MyFancyException)
    end
  end
end