Consider this code, which works (the loginWithEmail method gets expected as, well, expected):
_authenticationService = [[OCMockObject mockForClass:[AuthenticationService class]] retain];
[[_authenticationService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]];
Versus this code:
_authenticationService = [[OCMockObject mockForProtocol:@protocol(AuthenticationServiceProtocol)] retain];
[[_authenticationService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]];
The second code example fails 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 the 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>
This is using OCMock for iOS.
Why does expect
fail when the mock is a mockForProtocol
?
This is curious. I have added the following class into the iOS5 example 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 mock object is used? In your case, where does _authenticationService get passed to? What is the recipient doing to it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With