rspec delayed-job

Prueba de Rspec con retraso en el trabajo



delayed-job (2)

Tengo algunos procesos complejos de larga duración en mi aplicación. Estoy usando Rspec para probar métodos y clases individuales utilizados en los procesos, pero también me gustaría realizar muchos trabajos de fondo de extremo a extremo, con diferentes datos de prueba.

No pude encontrar nada en la wiki de retraso en el trabajo sobre esto, y esta pregunta SO parece interesante, pero realmente no entendí lo que está sucediendo aquí. ¿Cuál es la mejor manera de probar las cadenas retrayed_job con rSpec?

Puedo configurar fácilmente los datos de prueba con una fábrica y luego llamar a la clase que inicia el procesamiento en segundo plano. Espero que las pruebas tarden mucho en completarse.

código de fondo editado

class Singleplex def perform(batch_id,user) batch = start_batch(batch_id,user) ... do lots of stuff ... end handle_asynchronously :perform, queue: :singleplex, :run_at => Proc.new { 1.second.from_now }

spec / factories / batches.rb

FactoryGirl.define do factory :batch do batch_type ''singleplex'' name ''valid panel'' status ''ready'' end factory :batch_detail do chrom 7 chrom_start 140435012 chrom_end 140435012 target_offset 150 padding 4 primer3_parameter_id 1 snp_mask ''t'' status ''ready'' batch end end

Luego ejecuta la prueba de esta manera

describe Batch do it ''runs Singleplex for a valid panel'' do batch = FactoryGirl.create(:batch) user = User.find(1) status = Singleplex.new.perform(batch.id,user) expect(status.should == true) end end

Tengo dos problemas para resolver:

1) ¿Cómo se le dice a la prueba que espere hasta que se complete la llamada a la operación demorada antes de validar los resultados?

2) Para validar los resultados, tendré que verificar los valores en múltiples tablas. ¿Cuál es la mejor manera de hacer esto en Rspec?

EDITAR

Debo añadir que recibo un objeto de retraso de trabajo, por lo que, por supuesto, la comprobación de estado falla. Los trabajos toman al menos 10 minutos por lo general.

1) Batch runs Singleplex for a valid panel Failure/Error: expect(status.should == true) expected: true got: #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod/nobject:...", last_error: nil, run_at: nil, locked_at: nil, failed_at: nil, locked_by: nil, queue: nil, created_at: nil, updated_at: nil> (using ==)


Hay algunas maneras de hacer esto. Todos ellos requieren que ejecutes el trabajo en tu código.

Método 1: una prueba que DelayedJob::Worker cola el trabajo y luego le dice a DelayedJob::Worker que lo complete.

describe Batch do it ''runs Singleplex for a valid panel'' do batch = FactoryGirl.create(:batch) user = User.find(1) Singleplex.new.perform(batch.id,user) expect(Delayed::Worker.new.work_off).to eq [1, 0] # Returns [successes, failures] # Add expectations which check multiple tables to make sure the work is done end end

Método 2: una prueba que ejecuta el trabajo en cuestión con cola desactivada y comprueba los resultados deseados. Puede demorar la cola llamando a Delayed::Worker.delay_jobs = false en algún lugar de la configuración de prueba o en un bloque before .

before(:each) do Delayed::Worker.delay_jobs = false end describe Batch do it ''runs Singleplex for a valid panel'' do batch = FactoryGirl.create(:batch) user = User.find(1) Singleplex.new.perform(batch.id,user) # expectations which check that the work is done end end

Sin embargo, se sabe que este método causa problemas con las devoluciones de llamada .

Método 3: escriba un observador que observe los trabajos nuevos que se creen y los ejecute. De esta forma, no tendrá que declarar manualmente "work_off" en sus pruebas. Artsy tiene una esencia para esto .

También es una buena idea tener pruebas en otros lugares que aseguren que los trabajos se pongan en cola como se esperaba

it "queues welcome when a user is created" do expect(Delayed::Job.count).to eq 0 # Create user step expect(Delayed::Job.count).to eq 1 # You should really be looking for the count of a specific job. end


Si desea ejecutar un trabajo retrasado en una sola prueba o un conjunto de pruebas, puede agregar esto a su spec_helper.rb

config.around(:each, :run_delayed_jobs) do |example| Delayed::Worker.delay_jobs = false example.run Delayed::Worker.delay_jobs = true end

Y llámalo con:

it ''runs the job'', :run_delayed_jobs do # delayed job magic end