2012-09-27 12 views
8

consideran este código, que funciona (el método loginWithEmail se espera que, así, se espera):OCMock, ¿por qué no puedo esperar el método en un protocolo?

_authenticationService = [[OCMockObject mockForClass:[AuthenticationService class]] retain]; 
[[_authenticationService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]]; 

Versus este código:

_authenticationService = [[OCMockObject mockForProtocol:@protocol(AuthenticationServiceProtocol)] retain]; 
[[_authenticationService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]]; 

El segundo ejemplo de código falla en la línea 2 con la siguiente de error:

*** -[NSProxy doesNotRecognizeSelector:loginWithEmail:andPassword:] called! Unknown.m:0: error: -[MigratorTest methodRedacted] : *** 
-[NSProxy doesNotRecognizeSelector:loginWithEmail:andPassword:] called! 

AuthenticationServiceProtocol declara el método:

@protocol AuthenticationServiceProtocol <NSObject> 
@property (nonatomic, retain) id<AuthenticationDelegate> authenticationDelegate; 

- (void)loginWithEmail:(NSString *)email andPassword:(NSString *)password; 
- (void)logout; 
- (void)refreshToken; 

@end 

Y se implementa en la clase:

@interface AuthenticationService : NSObject <AuthenticationServiceProtocol> 

Esto es usando OCMock para iOS.

¿Por qué expect falla cuando el simulacro es mockForProtocol?

+0

¿Está compilando OCMock desde la fuente? Sería interesante poner un punto de interrupción en el método 'methodSignatureForSelector:' de 'OCProtocolMockObject'. –

+0

No se crea desde la fuente, solo se descargó la biblioteca estática. – driis

+0

¿Se puede publicar la declaración del protocolo real? –

Respuesta

2

Esto es curioso. He añadido la siguiente clase en el proyecto ejemplo iOS5:

@protocol AuthenticationServiceProtocol 

- (void)loginWithEmail:(NSString *)email andPassword:(NSString *)password; 

@end 

@interface Foo : NSObject 
{ 
    id<AuthenticationServiceProtocol> authService; 
} 

- (id)initWithAuthenticationService:(id<AuthenticationServiceProtocol>)anAuthService; 
- (void)doStuff; 

@end 

@implementation Foo 

- (id)initWithAuthenticationService:(id<AuthenticationServiceProtocol>)anAuthService 
{ 
    self = [super init]; 
    authService = anAuthService; 
    return self; 
} 

- (void)doStuff 
{ 
    [authService loginWithEmail:@"x" andPassword:@"y"]; 
} 

@end 

@implementation ProtocolTests 

- (void)testTheProtocol 
{ 
    id authService = [OCMockObject mockForProtocol:@protocol(AuthenticationServiceProtocol)]; 
    id foo = [[Foo alloc] initWithAuthenticationService:authService]; 

    [[authService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]]; 

    [foo doStuff]; 

    [authService verify]; 
} 

@end 

Cuando funciono esto en Xcode Version 4.5 (4G182) contra el iPhone 6.0 Simulador pasa la prueba. ¿Hay alguna diferencia en cómo se usa el objeto simulado? En su caso, ¿a dónde se transfiere _authenticationService? ¿Qué le está haciendo el destinatario?

+0

Hola Erik, gracias por tu respuesta. Intenté reproducir esto en un proyecto de prueba vacío diferente, y no puedo, así que tendré que investigar exactamente qué desencadena el comportamiento. Te llamaré si encuentro algo. FYI, el error ocurre en la llamada 'expect', antes de que el simulacro pase a cualquiera de mis códigos bajo prueba. – driis

+0

@driis Traté de reproducirlo también pero no pude. ¿Qué versión de OCMock estás usando? –

+0

@Erik ¿Cómo podemos obtener el argumento pasado durante la llamada al método delegado? Al igual que en el caso anterior, el método doStuff llama al método authService con argumentos @ "x" y @ "y". ¿Cómo puedo leer @ "x" y @ "y" en el caso de prueba? –

Cuestiones relacionadas