Задержка задания не обрабатывается в rspec - PullRequest
34 голосов
/ 07 июля 2010

Я пытаюсь запустить rspecs для пользовательского отложенного задания (GetPage :: GetPageJob), но у меня проблема.

Когда я запускаю их, задания хорошо ставятся в очередь (то есть хорошо вставляются в таблицу delayed_jobs), но они не обрабатываются рабочим заданием. Действительно, после запуска «rake jobs: work RAILS_ENV = test» в первом терминале и после запуска specs во втором терминале я не вижу никаких результатов от рабочего задания в первом терминале.

С другой стороны, задания хорошо обрабатываются, если я ставлю их в очередь через «скрипт / тест консоли». Так что я немного растерялся.

Как со спецификациями, так и со скриптом / консолью, строка, которую я использую для постановки в очередь, выглядит следующим образом:

Delayed::Job.enqueue GetPage::GetPageJob.new("http://cnn.com")

Есть идеи?

Ответы [ 4 ]

93 голосов
/ 16 августа 2011

Самый простой способ проверить поставленные в очередь задачи Delayed :: Job в RSpec - это запускать их в режиме реального времени. Просто добавьте следующую строку в ваши тесты RSpec:

Delayed::Worker.delay_jobs = false

Это приведет к тому, что ваши задания будут обрабатываться сразу после постановки в очередь, а не в отдельном потоке. Обычно это то, что вы хотите для тестирования, так как это детерминировано.

Два предостережения

  • Если вы пытаетесь проверить ошибки синхронизации, условия гонки и т. Д., Этот подход не поможет (поскольку задания обрабатываются в том же потоке, что и RSpec)

  • В текущей версии delayed_job (2.1.4) имеется незначительная ошибка, из-за которой перехватчики обратного вызова (постановка в очередь, before, success, error, fail) не вызываются, когда для Delayed::Worker.delay_jobs установлено значение false

Два обходных пути

Если вам нужно протестировать ловушки обратного вызова, я знаю два обходных пути:

  • Получить последнюю ветку master из github. (Я не пробовал это, потому что мне нужна стабильная версия)

  • Вместо установки Delayed::Worker.delay_jobs = false явно вызовите механизм запуска ди-джея в вашем тестовом коде следующим образом:

    successes, failures = Delayed::Worker.new.work_off

Это обработает все, что находится в очереди заданий (опять же, в том же потоке, что и тесты RSpec) и вернет два числа: число выполненных заданий и число неудачных заданий. В настоящее время я использую этот подход, и он делает все, что мне нужно.

3 голосов
/ 09 января 2011

Вам нужно будет запускать рабочий процесс изнутри ваших тестов, а не из другого процесса.Попробуйте:

worker = Delayed::Worker.new(:max_priority => nil, :min_priority => nil, :quiet => true)
worker.work_off
3 голосов
/ 17 июля 2010

В прошлом я пытался провести сквозной тест логики -> отложенное задание -> выполнить задание, и это было слишком много вещей. Я думаю, что вместо того, чтобы тестировать все это с помощью RSpec, вы могли бы сосредоточиться на тестировании каждого аспекта.

Итак, проверьте, что задание вставлено. Затем проведите еще один тест, который проверяет, что должно произойти при выполнении задания.

В качестве альтернативы, макет отложенного задания, так что когда вы ставите в очередь задание, оно выполняет его сразу.

1 голос
/ 04 сентября 2013

Я использую опцию конфигурации для запуска заданий в режиме реального времени:

# config/initializers/delayed_job_config.rb
Delayed::Worker.delay_jobs = !Rails.env.test?
...