编写一个用于 Sidekiq worker 的测试

24

我正在使用rspec-sidekiq宝石库(https://github.com/philostler/rspec-sidekiq)来帮助测试我编写的一个worker,但出现了一些原因导致我的测试失败。

这是我的测试内容:

require 'spec_helper'

describe CommunicationWorker do
  it { should be_retryable false }

  it "enqueues a communication worker" do
    subject.perform("foo@bar.com", "bar@foo.com", [1,2,3])
    expect(CommunicationWorker).to have_enqueued_jobs(1)
  end
end

这是错误内容:

 1) CommunicationWorker enqueues a communication worker
     Failure/Error: expect(CommunicationWorker).to have_enqueued_jobs(1)
       expected CommunicationWorker to have 1 enqueued job but got 0
     # ./spec/workers/communication_worker_spec.rb:9:in `block (2 levels) in <top (required)>'

我根据他们在维基上的示例进行了低级别测试,但对我来说它不起作用...有什么原因会导致它不起作用?


你曾经让它工作了吗?我也遇到了同样的问题。 - hiattp
2个回答

32

这里有两个需要测试的方面,一个是作业在队列中的异步排队,另一个是作业的执行。

您可以通过实例化作业类并调用perform()来测试作业的执行。

您可以通过在作业类上调用perform_async()来测试作业的排队。

要测试测试中的期望结果,您应该执行以下操作:

 it "enqueues a communication worker" do
    CommunicationWorker.perform_async("foo@bar.com", "bar@foo.com", [1,2,3])
    expect(CommunicationWorker).to have(1).jobs
  end

然而,这只是对Sidekiq框架进行测试,并不是一个有用的测试。我建议编写针对作业本身的内部行为的测试:

 it "enqueues a communication worker" do
    Widget.expects(:do_work).with(:some_value)
    Mailer.expects(:deliver)

    CommunicationWorker.new.perform("foo@bar.com", "bar@foo.com", [1,2,3])
  end

2
在回答这个问题时,我猜have_enqueued_jobs仍然有效,但现在正确的语法是have(1).jobs - harasho
谢谢!对于 Google:has_enqueued_job?我找到了零个结果。 - Michael
1
对于rspec 3,这将起作用: expect(CommunicationWorker.jobs.size).to eq(1) - mikkeljuhl

3
测试方法是什么?尝试使用 Sidekiq::Testing.fake! do <your code> end 将现有的测试包装起来。这将确保使用假队列。如果 Sidekiq 的测试方法是 'inline',则 worker 将立即执行(因此您的队列长度为 0)。
查看更多信息: https://github.com/mperham/sidekiq/wiki/Testing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接