He estado escribiendo pruebas con instance_doubles para sustituir las cadenas de mensajes cuando necesito más granularidad en medio de la cadena. Pero, me pregunto si estoy haciendo las cosas de la manera difícil.
Aquí está el método que quiero probar:
def run_produceable_job # Delete any jobs that exist, but haven't started, in favor of this new job Delayed::Job.where(queue: 'produceable', locked_at: nil).delete_all ProduceableJob.perform_later end Para la llamada Delayed::Job , es importante que verifique que el nombre de la cola sea el esperado. También quiero asegurarme de que Delayed::Job reciba .delete_all al final
Me gustaría hacer algo como esto:
expect(Delayed::Job).to receive(:where).with(queue: 'produceable', locked_at: nil).and_then_receive(:delete_all) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^¿RSpec ofrece algún tipo de encadenamiento para recibir? He hojeado los documentos, pero no puedo encontrar nada que hable específicamente sobre agregar múltiples recepciones.
¿O voy a tener que hacerlo por el camino largo?
ar_relation = instance_double ActiveRecord::Relation allow(Delayed::Job).to receive(:where).with(queue: 'produceable', locked_at: nil).and_return(ar_relation) allow(ar_relation).to receive(:delete_all) expect(Delayed::Job).to receive(:where).with(queue: 'produceable', locked_at: nil) expect(ar_relation).to receive(:delete_all)En mi humilde opinión, tienes que ir por el camino largo. No hay manera más corta de describirlo.
Independientemente de eso, le recomendaría que piense demasiado en su estrategia de prueba. En este momento, prueba que se llama a una combinación muy específica de métodos, pero no si estas llamadas a métodos realmente están haciendo lo que usted quiere que hagan.
En su lugar, crearía un registro de ejemplo que debería eliminarse (y quizás un par que no debería eliminarse), luego ejecutaría el trabajo y luego probaría que solo se eliminó el registro esperado.
Por ejemplo como este:
let!(:record_to_be_deleted) { Delayed::Job.create!(queue: 'produceable', locked_at: nil) } let!(:records_to_stay) do [ Delayed::Job.create!(queue: 'produceable', locked_at: Time.current), Delayed::Job.create!(queue: 'default', locked_at: nil) ] end it "should remove only expected records" do expect { instance.run_produceable_job }.to chance { DelayedD::Job.count }.from(3).to(2) expect { record_to_be_deleted.reload }.to raise_error(ActiveRecord::RecordNotFound) endLa regla general es probar el resultado esperado, no la implementación específica. Debido a que la implementación puede cambiar, se refactorizará o podría romperse en versiones futuras.