Prueba de una barredora con RSpec en Rails
-
23-08-2019 - |
Pregunta
Quiero asegurarme de que mi barredora está siendo llamado en su caso, así que traté de añadir algo como esto:
it "should clear the cache" do
@foo = Foo.new(@create_params)
Foo.should_receive(:new).with(@create_params).and_return(@foo)
FooSweeper.should_receive(:after_save).with(@foo)
post :create, @create_params
end
Pero apenas consigo:
<FooSweeper (class)> expected :after_save with (...) once, but received it 0 times
He intentado encender el almacenamiento en caché en la configuración de prueba, pero eso no hace ninguna diferencia.
Solución
Como ya lo ha dicho el almacenamiento en caché tiene que estar habilitado en el entorno para que esto funcione. Si se trata de personas con discapacidad entonces mi ejemplo a continuación se producirá un error. Es probablemente una buena idea para permitir temporalmente esta en tiempo de ejecución de las especificaciones de su caché.
'after_save' es un método de instancia. A configurar una expectativa de un método de clase, por lo que está fallando.
La siguiente es la mejor manera que he encontrado para establecer esta expectativa:
it "should clear the cache" do
@foo = Foo.new(@create_params)
Foo.should_receive(:new).with(@create_params).and_return(@foo)
foo_sweeper = mock('FooSweeper')
foo_sweeper.stub!(:update)
foo_sweeper.should_receive(:update).with(:after_save, @foo)
Foo.instance_variable_set(:@observer_peers, [foo_sweeper])
post :create, @create_params
end
El problema es que los observadores de Foo (barrenderos son una subclase de los observadores) se establecen las botas cuando los disipadores de arriba, así que tenemos que insertar nuestra maqueta barredora directamente en el modelo con 'instance_variable_set'.
Otros consejos
Barredoras son Singleton y se crean instancias en el comienzo de la prueba rspec. Como tal se puede llegar a ella a través de MySweeperClass.instance (). Esto funcionó para mí (Rails 3.2):
require 'spec_helper'
describe WidgetSweeper do
it 'should work on create' do
user1 = FactoryGirl.create(:user)
sweeper = WidgetSweeper.instance
sweeper.should_receive :after_save
user1.widgets.create thingie: Faker::Lorem.words.join("")
end
end
Asumiendo que tiene:
- una clase
FooSweeper
- una clase
Foo
con un atributobar
foo_sweeper_spec.rb
:
require 'spec_helper'
describe FooSweeper do
describe "expiring the foo cache" do
let(:foo) { FactoryGirl.create(:foo) }
let(:sweeper) { FooSweeper.instance }
it "is expired when a foo is updated" do
sweeper.should_receive(:after_update)
foo.update_attribute(:bar, "Test")
end
end
end