OCMock, why can't I expect a protocol method?

Consider this code that works (loginWithEmail method is expected as expected):

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

Compared to this code:

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

The second code example does not work on line 2 with the following error:

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

AuthenticationServiceProtocol declares a method:

 @protocol AuthenticationServiceProtocol <NSObject> @property (nonatomic, retain) id<AuthenticationDelegate> authenticationDelegate; - (void)loginWithEmail:(NSString *)email andPassword:(NSString *)password; - (void)logout; - (void)refreshToken; @end 

And it is implemented in the class:

 @interface AuthenticationService : NSObject <AuthenticationServiceProtocol> 

It uses OCMock for iOS.

Why expect fail when the layout is mockForProtocol ?

+8
ios objective-c mocking ocmock
source share
1 answer

This is curious. I added the following class to the iOS5 sample project:

 @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 

When I run this in Xcode version 4.5 (4G182) against the iPhone 6.0 simulator, the test passes. Is there any difference in how the layout is used? In your case, where does _authenticationService go? What does the recipient do with it?

+2
source share

All Articles