2010-12-07 6 views
31

Me preguntaba cómo probar una llamada find_each en rspec. Estoy acostumbrado a tropezar simplemente lo que yo quiero que mis modelos para volver por lo que no se basan en datos de pruebas en el PP como esto:¿Cómo puedo encontrar find_each para la prueba rspec en rieles 3

MyClass.stub(:find).and_return(my_mock) 

Sin embargo, en otra clase que estoy haciendo esto:

MyClass.find_each do |instance_of_my_class| 
    do_stuff_here_on(instance_of_my_class) 
end 

me parece que si hago esto:

MyClass.stub(:find_each).and_return([one_mock, two_mock]) 

en la prueba de especificaciones, no se está ejecutando la parte de "hacer cosas aquí". ¿Alguien sabe cómo encontrar un find_each para la prueba de rspec?

Respuesta

35

Puede utilizar and_yield hacer rspec llamar el bloque pasó a la maqueta:

MyClass.stub(:find_each).and_yield(one_mock).and_yield(two_mock) 
+0

Al hacer esto, se obtiene el siguiente error | mis simulacros aquí | para bloquear con arity de 1. Si paso los simulacros como una matriz, no tiene problema, pero la instancia_de_mi_clase en el bloque find_each es la matriz y no los elementos en ella. – Aaron

+4

¿Qué tal '.and_yield (one_mock) .and_yield (two_mock)'? – zetetic

+0

tiene toda la razón, zetetic: me aseguraré de probar mi consejo la próxima vez :) He editado mi respuesta para incluir su corrección. – Iain

2

El objetivo de anotar un método es que el método devuelva un valor esperado y no ejecute su contenido. Si tiene un montón de lógica dentro del método find_each, recomendaría moverlo a un método diferente y probar esa lógica por separado. Luego puede probar que se llama a su método durante la ejecución.

Aquí hay un ejemplo muy alto nivel:

class Example1 
    def my_method 
    # some logic 
    end 
end 

class Example2 
    def my_other_method 
    Example1.find_each(&:my_method) 
    end 
end 

Rspec:

describe Example1 do 
    it "should return something" do 
    example = Example1.new 
    example.my_method.should == something 
    end 
end 

describe Example2 do 
    it "should call my_method on Example1" do 
    example1 = mock(:example1, :my_method => true) 
    example2 = Example2.new 

    example1.should_receive(:my_method) 
    example2.my_other_method 
    end 
end 
+0

realidad estoy haciendo la lógica en otro método que estoy probando. He actualizado el bloque find_each en mi pregunta para reflejar esto. Estoy intentando probar que esto se lleva a cabo en todos los simulacros que paso. – Aaron

1

Este debería hacerlo:

MyClass.stub(:find_each) {|block| 
    block.call 
    [one_mock, two_mock] 
} 

Si do_stuff_here_on no es alcanzable en todo el mundo, p. un método de instancia en some_object, usted necesitará un poco instance_eval para obtener el alcance adecuado para el bloque:

MyClass.stub(:find_each) {|block| 
    some_object.instance_eval(&block) 
    [one_mock, two_mock] 
} 
Cuestiones relacionadas