как протестировать хуки обратного вызова delayed_job с помощью RSpec

Я хотел бы убедиться, что перехватчики обратного вызова 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 знает ответ во сне... ;)

(Предупреждение: в моем конкретном случае используется класс 'shim' между MyJob и DJ. Ответ на этот простой случай может вызвать более сложное продолжение!)


person fearless_fool    schedule 16.08.2011    source источник
comment
Если вы хотите убедиться, что вызывается только after, не могли бы вы отказаться от требования .with(an_instance_of...? В качестве примечания, я предпочитаю использовать Delayed::Worker.new(:quiet =› true).work_off, чтобы заглушить воркер и любое его нытье. Я признаю, однако, что может быть исключение, которое я не вижу из-за этого.   -  person Nick    schedule 23.09.2011


Ответы (2)


ИМХО, я не думаю, что это лучший выход...

Делая это, вы пытаетесь определить поведение DelayedJob, а не своего приложения, и у DJ уже есть собственный набор тестов.

В любом случае, как насчет того, чтобы издеваться над самой DelayedJob? Возможно, вы можете указать, сделав это, что ваш MockedJob вызовет ваш хук после обработки, и вы можете соответственно создать свои сопоставления/ожидания...

person Rudy Seidinger    schedule 14.05.2012
comment
Отсутствуя в этом вопросе более двух лет (!) Я думаю, вы правы: вопрос, как написано, только пытается проверить поведение ди-джея и ничего не делает для проверки моего кода. - person fearless_fool; 21.06.2014

Мое предложение состояло бы в том, чтобы посмотреть, создает ли таблица 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
person heavysixer    schedule 07.10.2011