为 sidekiq 工作人员编写测试

Posted

技术标签:

【中文标题】为 sidekiq 工作人员编写测试【英文标题】:Writing tests for a sidekiq worker 【发布时间】:2013-09-16 05:51:00 【问题描述】:

我正在使用 rspec-sidekiq gem (https://github.com/philostler/rspec-sidekiq) 来帮助测试我正在编写的工人,但由于某种原因,我的测试一直失败。

这是我的测试:

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)>'

我在他们的 wiki 上基于他们的示例进行了低级测试,但它对我不起作用......为什么这不起作用?

【问题讨论】:

你有没有得到这个工作?我遇到了同样的问题。 【参考方案1】:

这里有两件事要测试,作业在队列中的异步入队和作业的执行。

您可以通过实例化作业类并调用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

【讨论】:

在给出这个答案时,我猜have_enqueued_jobs 仍然有效,但现在正确的语法是have(1).jobs 谢谢!对于谷歌:has_enqueued_job?我发现该字符串的结果恰好为零 对于 rspec 3,这将起作用:expect(CommunicationWorker.jobs.size).to eq(1)【参考方案2】:

测试方法是什么?尝试使用Sidekiq::Testing.fake! do &lt;your code&gt; end 包装您现有的测试。这将确保使用假队列。如果 sidekiq 的测试方法是“内联”的,worker 将立即执行(因此您的队列长度为 0)。

查看:https://github.com/mperham/sidekiq/wiki/Testing 了解更多信息。

【讨论】:

以上是关于为 sidekiq 工作人员编写测试的主要内容,如果未能解决你的问题,请参考以下文章

Sidekiq 与连接到不同 Redis 实例的工作人员

Sidekiq 工作人员正在泄漏内存

Sidekiq 工作人员的不同日志级别 - Ruby 方法?

每个 sidekiq 工作人员有多种方法

工作人员完成后 Sidekiq 未释放内存

Sidekiq 是不是按照发送给工作人员的顺序执行作业?