ruby on rails - run - Rspec: Cómo asignar la variable de instancia en la especificación del controlador
rspec documentation (3)
class TestController < AplicationController
#....
private
def some_method
unless @my_variable.nil?
#...
return true
end
end
end
Quiero probar some_method
directamente en la especificación del controlador:
require ''spec_helper''
describe TestController do
it "test some_method"
phone = Phone.new(...)
controller.assign(:my_variable,phone) #does not work
controller.send(:some_method).should be_true
end
end
¿Cómo puedo configurar la variable de instancia @my_variable
desde la especificación del controlador?
Al probar los métodos privados en los controladores, en lugar de usar send
, tiendo a usar un controlador anónimo porque no quiero llamar directamente al método privado, sino a la interfaz del método privado (o, en la prueba siguiente, anular efectivamente esa interfaz) . Entonces, en tu caso, tal vez algo así como:
require ''spec_helper''
describe TestController do
controller do
def test_some_method
some_method
end
end
describe "a phone test with some_method" do
subject { controller.test_some_method }
context "when my_variable is not nil" do
before { controller.instance_variable_set(:@my_variable, Phone.new(...)) }
it { should be_true }
end
context "when my_variable is nil" do
before { controller.instance_variable_set(:@my_variable, nil) }
it { should_not be_true } # or should be_false or whatever
end
end
end
Existe una buena discusión sobre el tema de la prueba directa de métodos privados en este Q & A , que me empujó hacia el uso de controladores anónimos, pero su opinión puede diferir.
No creo que desee acceder a una variable de instancia desde su controlador de especificaciones, ya que la especificación debe probar el comportamiento, pero siempre puede resguardar el método privado. En tu caso, debería ser algo como esto (en este ejemplo, no tiene mucho sentido):
describe TestController do
it "test some_method"
phone = Phone.new(...)
controller.stub(:some_method).and_return(true)
controller.send(:some_method).should be_true
end
end
Si esto no es lo que está buscando, eche un vistazo a esto: ¿Cómo establecer la variable de instancia privada utilizada en una prueba de método?
instance_eval
es una forma relativamente limpia de lograr esto:
describe TestController do
it "test some_method" do
phone = Phone.new(...)
controller.instance_eval do
@my_variable = phone
end
controller.send(:some_method).should be_true
end
end
En este caso, usar do...end
en instance_eval
es overkill, y esas tres líneas se pueden acortar a:
controller.instance_eval {@my_variable = phone}