【问题标题】:how to test delayed_job callback hooks using RSpec如何使用 RSpec 测试 delay_job 回调挂钩
【发布时间】:2011-10-27 17:57:54
【问题描述】:

我想验证是否调用了延迟作业回调挂钩,但我不知道如何让 RSpec 执行此操作,尤其是在涉及多层类时。

假设我有一个这样的 ActiveRecord 模型:

class MyJob < ActiveRecord::Base
  def perform
    # do some stuff
  end
  def after(job)
    # called by delayed_job after perform completes
  end
end

从概念上来说,我想要按照这些思路进行 RSpec 测试(尽管我知道这不正确):

it 'should call the :after callback hook' do
  my_job = MyJob.create
  my_job.should_receive(:after).with(an_instance_of(Delayed::Backend::ActiveRecord::Job))

  Delayed::Job.enqueue(my_job)
  Delayed::Worker.new.work_off
end

我仔细研究了 stackoverflow、relishapp.com/rspec 以及我能想到的所有其他地方。不会太难吧? (我敢打赌@zetetic 会在睡梦中知道答案……;)

(警告:我的实际案例在 MyJob 和 DJ 之间使用了一个“shim”类。这个简单案例的答案可能会引发更复杂的后续操作!)

【问题讨论】:

  • 如果您只想验证 after 是否被调用,您不能放弃 .with(an_instance_of... 要求吗?作为旁注,我倾向于使用 Delayed::Worker.new(:quiet => true).work_off 来让工作人员和它可能发出的任何抱怨保持沉默。不过我承认,可能有一个我没有看到的例外。

标签: ruby-on-rails rspec delayed-job


【解决方案1】:

我的建议是查看 Jobs 表是否创建了新的作业记录,然后反省该记录的详细信息。我过去用过类似的东西。

it "should sync content from the remote CMS" do      
  DelayedJobs::CMS::Sync.module_eval do
  def perform
    url.should == "http://example.com/tools/datafeed/resorts/all"
    Report.sync!([{'id' => 1, 'name' => 'resort foo'}])
  end
end

lambda do
  Report.sync_all!
end.should change(Delayed::Job, :count)

lambda do
  Delayed::Job.work_off
end.should change(Resort, :count).by(2)
end

【讨论】:

    【解决方案2】:

    恕我直言,我认为这不是最好的做法......

    通过这样做,您是在尝试指定 DelayedJob 的行为,而不是您的应用,并且 DJ 已经有自己的一套测试。

    不管怎样,嘲笑 DelayedJob 本身怎么样?也许您可以通过这样做来指定您的 MockedJob 将在处理后调用您的钩子,并且您可以相应地创建匹配器/期望...

    【讨论】:

    • 已经离开这个问题两年多了(!)我认为你是对的:这个问题,正如所写的,只是试图验证 DJ 的行为,并没有做任何事情来验证我的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    相关资源
    最近更新 更多