Rspec 如何测试 Sidekiq 作业?

Rspec how to test a Sidekiq job?

提问人:Panpaper 提问时间:9/2/2021 更新时间:2/24/2023 访问量:4698

问:

我有一个 Sidekiq 工作,看起来像这样:

class Arbitrary::MarkSold < ApplicationJob
  def perform(item_id)
    return if Rails.env.test?
    item = Item.find_by(item_id)
    item.sold = true
    item.save
  end
end

以及相应的 RSpec 测试,如下所示:

Rspec.describe Arbitrary::MarkSold, type: :job do
  describe 'perform' do
    it 'runs' do
      expect(Arbitrary::Marksold).to receive(:perform).and_return(nil)
      MarkSold.new.perform(34)
    end
  end
end

当我尝试运行此测试时,我遇到以下错误:

Arbitrary::MarkSold does not implement: perform`.

但是,我可以清楚地看到这是有方法的。Arbitrary::MarkSoldperform

我已经阅读了方法存根,但无法从中找出正面或反面,或者弄清楚如何将其应用于这种情况。

我非常感谢除我链接的文档以外的任何指向文档的指针或链接。作为初学者,我发现 rspec 文档对初学者不是很友好。先谢谢你!

Ruby 版本:2.4.9 Rails 版本:5.1.7 RSpec 版本:3.7

Ruby-on-Rails 方法 rspec sidekiq 存根

评论


答:

1赞 dtakeshta 9/2/2021 #1

我用来测试作业是否排队,假设这是您尝试测试的内容。好像是这样。have_enqueued_job

https://relishapp.com/rspec/rspec-rails/docs/matchers/have-enqueued-job-matcher

评论

0赞 Panpaper 9/2/2021
谢谢!如何诱使此测试失败?
0赞 Panpaper 9/2/2021
这奏效了,但它并没有真正回答我的问题。我将编写一些其他测试,我希望更好地了解为什么我的代码不起作用。
0赞 João Fernandes 9/2/2021 #2

您正在执行的操作存在一些问题:

expect(Arbitrary::Marksold).to receive(:perform).and_return(nil)

在上面的代码片段中,您期望类接收 ,但您不希望实例接收 。这就是您收到错误的原因。Arbitrary::Marksoldperformperformdoes not implement: perform

你可以(我没有测试它,所以你可能需要调整一个或另一个东西):

marksold_spy = instance_spy(Arbitrary::Marksold)
allow(Arbitrary::Marksold).to(receive(:new).and_return(marksold_spy))
expect(marksold_spy).to(receive(:perform).and_return(nil))

但以上不是我的做法。我的做法是:

class Arbitrary::MarkSold
  include Sidekiq::Worker

  def perform(item_id)
    item = Item.update(item_id, sold: true)
  end
end

我的测试:

Rspec.describe Arbitrary::MarkSold, type: :job do
  describe 'perform' do
    it 'runs' do
      item = create(:item, sold: false)
      Sidekiq::Testing.inline! do
        described_class.perform_async(item.id)
      end
      expect(item.reload.sold).to be_truthy
    end
  end
end

要阅读更多关于 的信息,您可以通过此链接Sidekiq::Testing

0赞 Nicolas 2/24/2023 #3

对于下一个从 Google 偶然发现此页面的用户(像我一样)......

如果你想测试你的 Sidekiq 作业,请考虑一下,也许你要测试的是 Sidekiq 的内容,如果是这样,你可以像测试任何其他 ruby 对象一样直接测试它。perform

来源: https://github.com/sidekiq/sidekiq/wiki/Testing#testing-workers-directly