Reputation: 42602
I am using OCMock to do unit test.
I have a singleton class MyManager
:
@implementation MyManager
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
// This is the function I want to stub in my test case
- (NSInteger) getId{
return [self askBackendToReturn];
}
...
@end
In my test case, I want to stub the return of -(NSInteger) getId:
. I tired the following:
id mgrMock = OCMClassMock([MyManager class]);
// read OCMock 3 document, seems the return from OCMClassMock can be either a mocked class or mocked instance. The following line of code is according to its documents "Stubbing methods that create objects" http://ocmock.org/reference/#advanced-topics
OCMStub([[mgrMock alloc] init]).andReturn(mgrMock);
// Now I stub the function to return 1
OCMStub([mgrMock getId]).andReturn(1);
// test it, I still get the real id from backend, WHY?
MyManager *sharedManager = [MyManager sharedManager];
NSInteger mgrId = [sharedManager getId];
But when I run, the stub return is not working, it still return the real id. WHY?
Upvotes: 0
Views: 286
Reputation: 460
The reason it's returning the real id is because once [self alloc]
is called in your implementation, you are dealing with a new instance of MyManager
. This means that in [[self alloc] init]
you end up calling init
on a brand new instance who has no knowledge of the stubbed methods.
If you want to take the approach of stubbing the MyManager
initialization, you will have to stub both [mgrMock alloc]
and [mgrMock init]
to return your mock object.
In this spirit of unit testing, my suggestion is to nix this approach entirely, and instead simply stub sharedManager
to return mgrMock
. Your test is related to the singleton's Id, and should assume that initialization is working as expected.
Upvotes: 1