2012-03-28 10 views
13

Tengo una acción de controlador Rails para probar. En esa acción, ¿un método User.can? se invoca varias veces con diferentes parámetros. En uno de los casos de prueba, quiero asegurarme de que se invoque User.can? ('Withdraw'). Pero no me importan las invocaciones de User.can? con otros parámetrosMocha: cómo agregar la expectativa de un método cuando hay múltiples invocaciones con diferentes parámetros

def action_to_be_tested 
    ... 
    @user.can?('withdraw') 
    ... 
    @user.can?('deposit') 
    ... 
end 

me trataron a continuación en la prueba:

User.any_instance.expects(:can?).with('withdraw').at_least_once.returns(true) 

Pero la prueba ha fallado con el mensaje que indica la invocación inesperada de User.can ('depósito')?. Si agrego otra expectativa con el parámetro 'depósito', la prueba pasó. Pero me pregunto si hay alguna manera de que pueda centrarme en la invocación con el parámetro 'retirar' (porque otras invocaciones son irrelevantes para este caso de prueba).

Respuesta

15

acabo de encontrar una solución, por apagando invocaciones con los parámetros irrelevantes:

User.any_instance.expects(:can?).with('withdraw').at_least_once.returns(true) 
User.any_instance.stubs(:can?).with(Not(equals('withdraw'))) 

http://mocha.rubyforge.org/classes/Mocha/ParameterMatchers.html#M000023

+0

Sabía [la API] (http://gofreerange.com/mocha/docs/Mocha/Expectation.html#with-instance_method) valores literales compatibles (comparaciones directas con variables), o ceder al bloque, pero No estoy seguro de dónde viene la construcción 'Not (...)'. ¿Podrías hablar sobre eso con más detalle? – Pysis

+0

@Pysis 'Not()' proviene de [Mocha :: ParameterMatchers] (http://gofreerange.com/mocha/docs/Mocha/ParameterMatchers.html) que se utilizan con 'with()'. Pueden ser de camello como 'HasKey()' o de serpiente como 'has_key()'. 'Not' tiene que ser camel case porque es una palabra clave, sin embargo. –

12

se puede pasar de un bloque a with y tienen ese bloque inspeccionar los argumentos. El uso de eso, se puede construir una lista de invocaciones esperados:

invocations = ['withdraw', 'deposit'] 
User.any_instance.expects(:can?).at_most(2).with do |permission| 
    permission == invocations.shift 
end 

Cada vez que se llama can?, Mocha rendirá al bloque. El bloque extraerá el siguiente valor de la lista de invocaciones esperadas y lo comparará con la invocación real.

Cuestiones relacionadas