如何使用RSpec测试delayed_job回调挂钩

时间:2011-08-16 03:22:06

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

我想验证delayed_job回调挂钩是否被调用,但是我没有看到如何让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'课程。这个简单案例的答案可能会触发更复杂的后续行动!)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

恕我直言,我认为这不是最好的事情......

通过这样做,你试图规定DelayedJob的行为,而不是你的应用,DJ已经有了自己的测试。

无论如何,嘲笑DelayedJob本身怎么样?也许你可以通过这样做来指定你的MockedJob会在处理后调用你的钩子,你可以相应地创建你的匹配器/期望......