Ответ 1
Тестирование асинхронного типа, как это, всегда сложно. Что мы делаем:
-
В наших функциональных тестах мы убеждаемся, что задание завершено. Обычно используется мокка или что-то подобное с ожиданием. Если вы хотите запустить тестовый сервер redis, вы можете проверить правильность очереди и правильность параметров работы. Хотя вы тестируете Resque себя немного в этот момент.
-
Работы тестируются изолированно как единичные тесты. Поскольку у них просто есть метод класса, называемый
perform
, ваши модульные тесты довольно просты. В вашем случае вы должны проверить, что ChangeRecorderJob.perform делает то, что вы хотите. Мы склонны тестировать, что задания находятся в соответствующей очереди, что параметры для задания действительны и что работа делает то, что мы хотим. -
Теперь, чтобы проверить все вместе, это сложная часть. Я сделал это двумя разными способами, и у каждого есть плюсы и минусы:
-
Monkey-patch Resqueue.enqueue для выполнения задания синхронноС точки зрения resque 1.14.0 вы можете использоватьResque.inline = true
в своем инициализаторе вместо перехвата обезьян - Имитировать рабочего, который выкидывает задание из очереди и фактически запускается в разветвленном процессе.
-
Выполнение задания синхронно намного проще. Вы просто загрузите что-то вроде следующего в свой spec_helper:
module Resque alias_method :enqueue_async, :enqueue def self.enqueue(klass, *args) klass.new(0, *args).perform end end
Забастовкa >
С resque 1.14.0 вы можете просто установить Resque.inline = true
в свой инициализатор вместо патча обезьян. Если вы застряли в старой версии resque, необходимо запланировать обезьяну.
Обратите внимание, что, поскольку вы работаете синхронно здесь, вы будете нести расходы на свою долговременную работу. Возможно, более важно то, что вы собираетесь работать в одном и том же процессе, чтобы не было полностью точное представление о том, как будет работать ваша работа.
Чтобы выполнить задание в раздвоенном работнике, как и для resque, вам нужно сделать что-то вроде следующего:
def run_resque_job(job_class, job_args, opts={}) queue = opts[:queue] || "test_queue" Resque::Job.create(queue, job_class, *job_args) worker = Resque::Worker.new(queue) worker.very_verbose = true if opts[:verbose] if opts[:fork] # do a single job then shutdown def worker.done_working super shutdown end worker.work(0.01) else job = worker.reserve worker.perform(job) end end
Там небольшая задержка в том, чтобы заставить работника выкинуть задание из очереди. И, естественно, вам нужно будет запустить тестовый сервер redis, чтобы рабочий столкнулся с очередью.
Я уверен, что другие люди придумали умные способы тестирования работы resque. Это то, что работает для меня.