ruby-on-rails 如何测试Sidekiq作业?

x7rlezfr  于 2023-02-26  发布在  Ruby
关注(0)|答案(3)|浏览(165)

我有一个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::MarkSold有一个perform方法。
我读过方法存根,但不能从中得出结论,也不能弄清楚如何将其应用于这种情况。
我非常感谢任何指向文档的指针或链接。作为一个初学者,我发现rspec文档对初学者并不友好。提前感谢!
Ruby版本:2.4.9导轨版本:5.1.7 RSpec版本:3.7

svmlkihl

svmlkihl1#

我使用have_enqueued_job来测试作业是否进入队列(假设这就是您要测试的内容)。
https://relishapp.com/rspec/rspec-rails/docs/matchers/have-enqueued-job-matcher

am46iovg

am46iovg2#

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

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

在上面的代码片段中,您希望类Arbitrary::Marksold接收perform,但是您不希望instance接收perform,这就是您得到does 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的信息,可以查看this link

shstlldc

shstlldc3#

对于下一个用户偶然发现这个页面从谷歌(像我)...
如果您希望测试您的Sidekiq作业,请考虑您尝试测试的可能是perform的内容,如果是这样,您可以像测试任何其他ruby对象一样直接测试它。
资料来源:https://github.com/sidekiq/sidekiq/wiki/Testing#testing-workers-directly

相关问题