I am getting started with OSX TDD and OCMock, following http://pathfindersoftware.com/2009/01/testing-delegate-ocmock/.
Right now, I'm at the phase where my application displays a login upon startup and wish to test that a user with invalid/no credentials cannot login.
In detail, the AppDelegate will set itself as the login view controller's delegate, attempt to login (without setting credentials), then the delegate method didNotAuthorizeUser is called. However I'm getting an error in the test. Further details below.
Object setup
- AppDelegate - real object, instantiates the login vc and conforms to its protocol (
SomeDelegateProtocol) - LoginVC - mocked
- Application - mocked
Test.m
id mocklvc = [OCMockObject mockForClass:[LoginViewController class]];
[appDelegate setLoginViewController:mocklvc];
id qtApp = [OCMockObject mockForClass:[NSApplication class]];
id loginDelegate = [OCMockObject mockForProtocol:@protocol(SomeDelegate)];
[[mocklvc expect] setLoginDelegate:loginDelegate];
[[mocklvc expect] authenticateWithService];
[[loginDelegate expect] didNotAuthorizeUser];
//This row returns NSInternalConsistencyException
//OCMockObject[LoginViewController]
//unexpected method invoked setLoginDelegate:<AppDelegate>
[appDelegate applicationDidFinishLaunching:qtApp];
[mocklvc verify];
AppDelegate.m
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self.loginViewController setLoginDelegate:self];
}
LoginViewController.h/.m
@property (weak) id < SomeDelegate > loginDelegate;
Error message
When calling the application didFinishLaunchingWithOptions: I get the following error in the test,
NSInternalConsistencyException OCMockObject[LoginViewController] unexpected method invoked setLoginDelegate:<AppDelegate>
Do you think this is a good setup in the first place? Any ideas on how to rewrite the test or actually get around the error?
setLoginDelegate:is not getting called at all, or it is not getting called withloginDelegateas its argument. This makes some sense because I don't how your app delegate would know about the login delegate mock you created. I'd break your test down into two parts -- one testing that login gets called on launch, and the other testing the login controller directly. You might want to read through someone else's tests to get a feel for how they should be constructed. - Ben Flynn