2012-09-27 9 views
8

Rozważmy ten kod, który działa (metoda loginWithEmail dostaje Oczekuje się również, oczekiwany):OCMock, dlaczego nie mogę oczekiwać metody na protokole?

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

Versus ten kod:

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

Drugi przykład kod nie działa na linii 2 z następujących błąd:

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

AuthenticationServiceProtocol deklaruje metodę:

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

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

@end 

I to jest realizowane w klasie:

@interface AuthenticationService : NSObject <AuthenticationServiceProtocol> 

ten korzysta OCMock dla iOS.

Dlaczego expect kończy się niepowodzeniem, gdy próbą jest mockForProtocol?

+0

Budujesz OCMock ze źródła? Byłoby interesujące wstawienie punktu przerwania w metodzie 'methodSignatureForSelector:' obiektu 'OCProtocolMockObject'. –

+0

Nie budując ze źródła, właśnie pobrałem bibliotekę statyczną. – driis

+0

Czy możesz zamieścić rzeczywistą deklarację protokołu? –

Odpowiedz

2

To jest ciekawe. Dodałem następujące klasy na przykładzie projektu 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 

Gdy uruchomię to w Xcode w wersji 4.5 (4G182) przeciwko iPhone 6.0 Simulator testy przechodzi. Czy jest jakaś różnica w sposobie użycia obiektu próbnego? W twoim przypadku, gdzie przekazywana jest usługa _authenticationService? Co robi odbiorca?

+0

Cześć Erik, dziękuję za odpowiedź. Próbowałem odtworzyć to w osobnym pustym projekcie testowym, a nie mogę, więc będę musiała dokładnie zbadać, co wywołuje to zachowanie. Wrócę do ciebie, jeśli coś znajdę. FYI, błąd występuje w wywołaniu 'oczekiwać', zanim próbka zostanie przekazana do któregoś z testowanego kodu. – driis

+0

@driis Próbowałem go odtworzyć, ale nie mogłem. Z której wersji OCMock korzystasz? –

+0

@Erik Jak możemy uzyskać argument przekazany podczas delegowanego wywołania metody ?? Podobnie jak w powyższym przypadku metoda doStuff wywołuje metodę authService z argumentami @ "x" i @ "y". Jak mogę odczytać @ "x" i @ "y" w teście? –

Powiązane problemy