ruby-on-rails - mock - rspec allow
Probando after_commit con RSpec y burlándose (4)
Actualización para Rails5 .
El manejo de la devolución de llamada de hecho se ha corregido, pero es posible que aún deba usar #reload
generosamente.
Un ejemplo:
Dado un modelo que define una devolución de llamada posterior a la creación como tal:
after_create_commit { assign_some_association }
Puede especificar este comportamiento con:
describe "callbacks" do
describe "assigning_some_association" do
subject(:saving) { record.save!; record.reload } # reload here is important
let(:record) { build(:record) }
it "assigns some association after commit" do
expect{ saving }.to(
change{ record.some_association_id }.from(nil).to(anything)
)
end
end
end
Tengo un líder modelo y una devolución de llamada: after_commit :create, :send_to_SPL
Estoy usando Rails-4.1.0, ruby-2.1.1, RSpec.
1) Esta especificación no está pasando:
context ''callbacks'' do
it ''shall call /'send_to_SPL/' after create'' do
expect(lead).to receive(:send_to_SPL)
lead = Lead.create(init_hash)
p lead.new_record? # => false
end
end
2) Esta especificación no está pasando demasiado:
context ''callbacks'' do
it ''shall call /'send_to_SPL/' after create'' do
expect(ActiveSupport::Callbacks::Callback).to receive(:build)
lead = Lead.create(init_hash)
end
end
3) Este está pasando, pero creo que no está probando la devolución de llamada after_commit:
context ''callbacks'' do
it ''shall call /'send_to_SPL/' after create'' do
expect(lead).to receive(:send_to_SPL)
lead.send(:send_to_SPL)
end
end
¿Cuál es la mejor manera de probar las devoluciones de llamadas after_commit en Rails?
Estoy usando DatabaseCleaner , con una configuración donde puedo cambiar fácilmente entre transacción y truncamiento, donde se prefiere lo primero, debido a la velocidad, pero donde lo último se puede usar para probar las devoluciones de llamada.
Los controladores de before
y after
RSpec funcionan con ámbitos, por lo que si desea hacer un truncamiento del ámbito, defina un controlador before
;
config.before(:each, truncate: true) do
DatabaseCleaner.strategy = :truncation
end
Y ahora, para usar esta configuración para una describe
, un context
o it
bloque, debe declararlo como:
describe "callbacks", truncate: true do
# all specs within this block will be using the truncation strategy
describe "#save" do
it "should trigger my callback" do
expect(lead).to receive(:send_to_SPL)
lead = Lead.create(init_hash)
end
end
end
Configuración de enlace completa: (almacenar en spec/support/database_cleaner.rb
)
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, truncate: true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.append_after(:each) do
DatabaseCleaner.clean
end
end
Pensé que el comentario de Mihail Davydenkov merecía ser una respuesta:
También puede usar
subject.run_callbacks(:commit)
.
También tenga en cuenta que este problema (las devoluciones de llamada de confirmación no se realizan en las pruebas transaccionales) debe solucionarse en los rieles 5.0 o versiones posteriores, por lo que es posible que desee hacer una nota para eliminar cualquier solución alternativa que pueda utilizar mientras tanto cuando realice la actualización. Consulte: https://github.com/rails/rails/pull/18458
Trate de usar test_after_commit gema
o agregue el siguiente código en spec / support / helpers / test_after_commit.rb - Gist