with tutorial tests test run rails how ruby-on-rails ruby rspec rails-activejob

ruby-on-rails - tutorial - rspec with rails



Cómo comprobar qué está en cola en ActiveJob usando Rspec (6)

Hay una nueva extensión rspec que hace su vida más fácil.

require ''rails_helper'' RSpec.describe MyController do let(:user) { FactoryGirl.create(:user) } let(:params) { { user_id: user.id } } subject(:make_request) { described_class.make_request(params) } it { expect { make_request }.to enqueue_a(RequestMaker).with(global_id(user)) } end

Estoy trabajando en un método reset_password en una aplicación Rails API. Cuando se llega a este punto final, se pone en cola un ActiveJob que activará una solicitud a Mandrill (nuestro cliente de correo electrónico transaccional). Actualmente estoy intentando escribir las pruebas para garantizar que el ActiveJob esté en cola correctamente cuando se golpea el punto final del controlador.

def reset_password @user = User.find_by(email: params[:user][:email]) @user.send_reset_password_instructions end

El send_reset_password_instructions crea algunas url, etc. antes de crear el ActiveJob cuyo código está debajo:

class SendEmailJob < ActiveJob::Base queue_as :default def perform(message) mandrill = Mandrill::API.new mandrill.messages.send_template "reset-password", [], message rescue Mandrill::Error => e puts "A mandrill error occurred: #{e.class} - #{e.message}" raise end end

Por el momento, no estamos usando ningún adaptador para ActiveJob, por lo que solo quiero verificar con Rspec que ActiveJob está en cola.

Actualmente mi prueba se ve más o menos así (estoy usando chica de fábrica para crear el usuario):

require ''active_job/test_helper'' describe ''#reset_password'' do let(:user) { create :user } it ''should create an ActiveJob to send the reset password email'' do expect(enqueued_jobs.size).to eq 0 post :reset_password, user: { email: user.email } expect(enqueued_jobs.size).to eq 1 end end

¡Todo funciona en realidad, solo necesito crear las pruebas!

Estoy usando ruby ​​2.1.2 y rieles 4.1.6.

No veo ninguna documentación ni ayuda en ningún lugar de la web sobre cómo probar esto, por lo que cualquier ayuda sería muy apreciada.


La respuesta aceptada ya no me funciona, así que probé la sugerencia de Michael H. en los comentarios, que funciona.

describe ''whatever'' do include ActiveJob::TestHelper after do clear_enqueued_jobs end it ''should email'' do expect(enqueued_jobs.size).to eq(1) end end


Realmente no necesita probar la funcionalidad de ActiveJob. Solo prueba que tu código lo llame apropiadamente apagándolo

expect(MyJob).to receive(:perform_later).once post :reset_password, user: { email: user.email }

Los creadores de ActiveJob han usado las mismas técnicas para sus pruebas unitarias. Ver GridJob Testobject

Crean un GridJob de prueba en sus pruebas y anulan el método de ejecución, por lo que solo agrega trabajos a una matriz personalizada, ellos llaman a JobBuffer . Al final prueban si el buffer tiene trabajos en cola

Sin embargo, si nada puede evitar que realice una prueba de integración completa. Se supone que ActiveJob test_helper.rb se usa con minitest no con rspec. Entonces debes reconstruir su funcionalidad. Puedes simplemente llamar

expect(ActiveJob::Base.queue_adapter.enqueued_jobs).to eq 1

sin requerir nada

Actualización 1: Como se notó dentro de un comentario. ActiveJob::Base.queue_adapter.enqueued_jobs solo funciona configurándolo como queue_adapter en el modo de prueba.

# either within config/environment/test.rb config.active_job.queue_adapter = :test # or within a test setup ActiveJob::Base.queue_adapter = :test


Tuve algunos problemas, tal vez porque no incluí ActiveJob :: TestHelper, pero esto funcionó para mí ...

En primer lugar, asegúrese de que tiene el adaptador de cola configurado para :test como se muestran en las respuestas anteriores.

Por alguna razón, los trabajos de clear_enqueued_jobs en el bloque after no me funcionaron, pero la fuente muestra que podemos hacer lo siguiente: enqueued_jobs.clear

require ''rails_helper'' include RSpec::Rails::Matchers RSpec.describe "my_rake_task", type: :rake do after do ActiveJob::Base.queue_adapter.enqueued_jobs.clear end context "when #all task is run" do it "enqueues jobs which have been enabled" do enabled_count = get_enabled_count subject.execute expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(enabled_count) end it "doesn''t enqueues jobs which have been disabled" do enabled_count = get_enabled_count subject.execute expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(enabled_count) end end end


Rspec 3.4 ahora tiene have_enqueued_job cocinado, lo que hace que sea mucho más fácil de probar:

it "enqueues a YourJob" do expect { get :your_action, {} }.to have_enqueued_job(YourJob) end

tiene otras sutilezas para have_enqueued_job para permitirle verificar el (los) argumento (s) y el número de veces que debe ponerse en cola.


Prueba de carriles ActiveJob con RSpec

class MyJob < ActiveJob::Base queue_as :urgent rescue_from(NoResultsError) do retry_job wait: 5.minutes, queue: :default end def perform(*args) MyService.call(*args) end end require ''rails_helper'' RSpec.describe MyJob, type: :job do include ActiveJob::TestHelper subject(:job) { described_class.perform_later(123) } it ''queues the job'' do expect { job } .to change(ActiveJob::Base.queue_adapter.enqueued_jobs, :size).by(1) end it ''is in urgent queue'' do expect(MyJob.new.queue_name).to eq(''urgent'') end it ''executes perform'' do expect(MyService).to receive(:call).with(123) perform_enqueued_jobs { job } end it ''handles no results error'' do allow(MyService).to receive(:call).and_raise(NoResultsError) perform_enqueued_jobs do expect_any_instance_of(MyJob) .to receive(:retry_job).with(wait: 10.minutes, queue: :default) job end end after do clear_enqueued_jobs clear_performed_jobs end end