1

我有一个相对简单的工人,它使用 Excon 从互联网上抓取一些东西。我正在努力成为一名优秀的测试人员并使用 Webmock 来强制对 Internet 交互进行存根,这样我实际上是在根据各种存根交互测试代码应该做什么。

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

这是一个简单的工人示例(是的,我知道救援异常很糟糕,接下来我会修复它):

  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 在工作人员中捕获此错误?
  • 我应该完全做其他事情吗?

谢谢!

4

2 回答 2

1

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

于 2020-07-29T10:30:02.333 回答
1

为了让 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
于 2020-07-30T07:46:13.863 回答