2010-04-29 16 views
30

En mi trabajo diario me he echado a perder con Mockito's never() verification, que puede confirmar que nunca se llama a un método falso.¿Cómo puedo usar OCMock para verificar que nunca se llame a un método?

¿Hay alguna manera de lograr lo mismo usando Objective-C y OCMock? He estado usando el siguiente código, que funciona pero se siente como un truco. Estoy esperando que hay una manera mejor ...

- (void)testSomeMethodIsNeverCalled { 
    id mock = [OCMockObject mockForClass:[MyObject class]]; 
    [[[mock stub] andCall:@selector(fail) onObject:self] forbiddenMethod]; 

    // more test things here, which hopefully 
    // never call [mock forbiddenMethod]... 
} 

- (void)fail { 
    STFail(@"This method is forbidden!"); 
} 

Respuesta

59

Desde r69 de OCMock, es posible rechazar una llamada al método http://svn.mulle-kybernetik.com/OCMock/trunk/Source/Changes.txt

burla Niza/fallar rápido Cuando un método se llama en un objeto de burla que no se ha configurado con o expect o stub el objeto simulado generará una excepción . Este modo a prueba de rápida puede ser apagado mediante la creación de un "buen" simulacro:

id mock = [OCMockObject niceMockForClass:[SomeClass class]] 

Mientras agradables burla simplemente se ignoran todos los métodos inesperados es posible para no permitir métodos específicos:

[[mock reject] someMethod] 

Tenga en cuenta que en el modo de falla rápida, si se ignora la excepción , se volverá a ejecutar cuando se llame a la verificación. Esto hace posible asegurar que invocaciones no deseadas de notificaciones, etc. se pueden detectar.

Citado de: http://www.mulle-kybernetik.com/software/OCMock/#features

18

Por lo que yo sé OCMock fallará automáticamente cuando se llama a verificar y métodos que no han sido registrados fueron llamados. Un simulacro que no se quejaría si se llamaran métodos inesperados se llama un "buen simulacro".

- (void)testSomeMethodIsNeverCalled { 
    id mock = [OCMockObject mockForClass:[MyObject class]]; 

    [mock forbiddenMethod]; 
    [mock verify]; //should fail 
} 
+0

que trabajaron totalmente! No esperaba que fuera tan simple. Para ser el abogado del diablo, ¿crees que esto oculta la intención de la prueba? –

+0

@Justin: Bueno, requiere que el lector conozca el comportamiento de OCMock en este caso, lo cual no es demasiado obvio. Poner un comentario justo al lado de la llamada de verificación simulada debería ser suficiente para dejar en claro lo que debería suceder. Me gusta: '// verify debería fallar porque llamamos a un método inesperado en el simulacro. –

0

También podría intentar algo como esto, al estilo de JavaScript:

- (void)aMethod { 
    __block BOOL b = NO; 

    id mock = [OCMockObject mockForClass:[UIView class]]; 
    [[[mock stub] andDo:^(NSInvocation *i) { b = YES; }] resignFirstResponder]; 
    [mock resignFirstResponder]; 

    NSLog(@"And b is: %i", b); // This reads "And b is: 1" on the console 
} 

No estoy seguro de si hay fugas asociadas a este código. Tengo la idea de la lectura de esta página: http://thirdcog.eu/pwcblocks/

3

También puede verse en la necesidad de asegurar un método que nunca se pidió a un objeto que está parcialmente burla.

he creado una macro para esto:

#define andDoFail andDo:^(NSInvocation *invocation) { STFail(@"Should not have called this method!"); } 

lo uso como esto:

[[[_myPartialMock stub] andDoFail] unexpectedMethod]; 
+0

Si está utilizando OCMock moderno, le recomiendo usar' reject' como se indica en otras respuestas. –

6

partir de la versión 3.3 OCMock tiene OCMReject macro.

id mock = OCMClassMock([MyObject class]); 
    OCMReject([mock forbiddenMethod]); 

    // exception will raise 
    [mock forbiddenMethod]; 
0

asegurarse de que su método no llama, creo que tenemos que hacer una aserción antes de la testMethod llamada.Así que asegúrese de poner OCMReject antes de ejecutar el método de ensayo para escuchar qué método se activará cuando se ejecuta testMethod:

OCMReject([mock someMethod]); 
[mock testMethod]; 
+2

Si bien este fragmento de código puede resolver el problema, no explica por qué o cómo responde la pregunta. Por favor [incluya una explicación para su código] (// meta.stackexchange.com/q/114762/269535), ya que eso realmente ayuda a mejorar la calidad de su publicación. Recuerde que usted está respondiendo la pregunta a los lectores en el futuro, y es posible que esas personas no sepan los motivos de su sugerencia de código. ** Marcadores/revisores: ** [Para respuestas de solo código como este, downvote, no eliminar!] (// meta.stackoverflow.com/a/260413/2747593) – Patrick

+0

@Patrick Explicación agregada –

Cuestiones relacionadas