使用RSpec进行测试时,如何在Sidekiq工作程序中正确捕获错误



我有一个相对简单的工人,他使用Excon从互联网上获取一些东西。我正在努力成为一名优秀的测试人员,并使用Webmock强制执行互联网交互的存根,这样我就可以在各种存根交互的基础上测试代码应该做什么。

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

下面是一个简单的工人示例(是的,我知道拯救异常是不好的,我下一步会解决这个问题(:

include Sidekiq::Worker
sidekiq_options queue: 'fetch_article_content', retry: true, backtrace: true
def perform(url)
begin
Excon.get(url)
rescue Exception => e
Rails.logger.warn("error: #{e}")
nil
end
end
end

这里有一个简化的RSpec测试:

Sidekiq::Testing.inline!
work = FetchArticleContentWorker.new
work.perform("http://google.com")

启用Webmock后,这将导致Excon失败(见test.log文件(:

error: Real HTTP connections are disabled. Unregistered request: ...

然而,RSpec认为这很好:

.
Finished in 0.44487 seconds (files took 5.35 seconds to load)
1 example, 0 failures

我不确定我在这里做错了什么。我认为Sidekiqperform未能冒泡到RSpec是一个失败,但事实并非如此。

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

谢谢!

为了让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

两者都有效。两者都需要一些类似的RSpec:

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

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

最新更新