2012-06-03 15 views
22

Quiero probar si una función invoca otras funciones correctamente con Ruby minitest, pero no puedo encontrar una adecuada assert para probar desde el doc.¿Cómo afirmar cierto método se llama con Ruby minitest framework?

El código fuente
class SomeClass 
    def invoke_function(name) 
    name == "right" ? right() : wrong() 
    end 

    def right 
    #... 
    end 

    def wrong 
    #... 
    end 
end 
El código de prueba:
describe SomeClass do 
    it "should invoke right function" do 
    # assert right() is called 
    end 

    it "should invoke other function" do 
    # assert wrong() is called 
    end 
end 

Respuesta

21

Con minitest utiliza expect método para establecer la expectativa de un método que se llama en un objeto de burla como tal

obj = MiniTest::Mock.new 
obj.expect :right 

Si desea establecer la expectativa con parámetros y valores devueltos, entonces:

obj.expect :right, return_value, parameters 

Y para el objeto concreto de esta manera:

obj = SomeClass.new 
assert_send([obj, :right, *parameters]) 
+2

Para la versión objeto concreto, hay 'must_send' para cuando el uso de' minitest/spec' – Frost

+0

Dime si me falta algo, pero creo que la respuesta de @ jing-li a continuación es correcta al mencionar que 'assert_send' no es apropiado aquí. El OP quiere probar que se llama 'derecho' cuando se invoca' invoke_function'. Además, se necesita 'obj.verify' para asegurar que se llame' right' al objeto simulado en la primera parte de esta respuesta. Para cualquiera que lea esto, asegúrese de que sus pruebas fallen antes de que las aprueben. – monozok

+0

Creo que usar assert_send no es una opción segura. de acuerdo con los documentos: http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/Assertions.html#method-i-assert_send –

9

Minitest tiene una especial .expect :call para comprobar si se llama algún método.

describe SomeClass do 
    it "should invoke right function" do 
    mocked_method = MiniTest::Mock.new 
    mocked_method.expect :call, return_value, [] 
    some_instance = SomeClass.new 
    some_instance.stub :right, mocked_method do 
     some_instance.invoke_function("right") 
    end 
    mocked_method.verify 
    end 
end 

Lamentablemente esta característica no está documentada muy bien. Encontré sobre esto desde aquí: https://github.com/seattlerb/minitest/issues/216

0

De acuerdo con el ejemplo dado, no hay otra clase de delegado, y desea asegurarse de que el método se llama correctamente de la misma clase. A continuación, a continuación fragmento de código debería funcionar:

class SomeTest < Minitest::Test 
    def setup 
    @obj = SomeClass.new 
    end 

    def test_right_method_is_called 
    @obj.stub :right, true do 
     @obj.stub :wrong, false do 
     assert(@obj.invoke_function('right')) 
     end 
    end 
    end 

    def test_wrong_method_is_called 
    @obj.stub :right, false do 
     @obj.stub :wrong, true do 
     assert(@obj.invoke_function('other')) 
     end 
    end 
    end 
end 

La idea es stub [method_expect_to_be_called] devolviendo una sencilla verdadero valor, y en el bloque de código auxiliar afirmar que de hecho está siendo llamada y devolver la verdadero valor . Resolver el otro método inesperado es solo para asegurarse de que no se está llamando.

Nota: assert_send no funcionará correctamente. Por favor, consulte official doc.

De hecho, declaración abajo pasará, pero no significa que está funcionando como se esperaba:

assert_send([obj, :invoke_function, 'right']) 
# it's just calling invoke_function method, but not verifying any method is being called 
Cuestiones relacionadas