问题
My function under test is very simple:
@implementation MyHandler
...
-(void) processData {
DataService *service = [[DataService alloc] init];
NSDictionary *data = [service getData];
[self handleData:data];
}
@end
I use OCMock 3 to unit test it.
I need to stub the [[DataService alloc] init]
to return a mocked instance, I tried the answer from this question (which is an accepted answer) to stub [[SomeClazz alloc] init]
:
// Stub 'alloc init' to return mocked DataService instance,
// exactly the same way as the accepted answer told
id DataServiceMock = OCMClassMock([DataService class]);
OCMStub([DataServiceMock alloc]).andReturn(DataServiceMock);
OCMStub([DataServiceMock init]).andReturn(DataServiceMock);
// run function under test
[MyHandlerPartialMock processData];
// verify [service getData] is invoked
OCMVerify([dataServiceMock getData]);
I have set break point in function under test, I am sure [service getData]
is called when run unit test, but my above test code (OCMVerify) fails. Why?
Is it because the function under test is not using my mocked DataService
? But the answer accepted in that question tells it should work. I get confused now...
I want to know how to stub [[SomeClazz alloc] init]
to return mocked instance with OCMock?
回答1:
You cannot mock init
as it is implemented by the mock object itself. The reason that mocking init
works in the answer you linked is because it is a custom init method. If you do not want to use dependency injection, you will have to write a custom init
method for DataService
that you can mock.
In your implementation add a custom init
method:
// DataService.m
...
- (id) initForTest
{
self = [super init];
if (self) {
// custom initialization here if necessary, otherwise leave blank
}
return self;
}
...
Then update MyHandler
implementation to call this initForTest
:
@implementation MyHandler
...
-(void) processData {
DataService *service = [[DataService alloc] initForTest];
NSDictionary *data = [service getData];
[self handleData:data];
}
@end
And finally update your test to stub initForTest
:
id DataServiceMock = OCMClassMock([DataService class]);
OCMStub([DataServiceMock alloc]).andReturn(DataServiceMock);
OCMStub([DataServiceMock initForTest]).andReturn(DataServiceMock);
// run function under test
[MyHandlerPartialMock processData];
// verify [service getData] is invoked
OCMVerify([dataServiceMock getData]);
Feel free to rename initForTest
, so long as it isn't called init
.
来源:https://stackoverflow.com/questions/37654226/stub-someclazz-alloc-init-not-work-but-accepted-answer-says-it-should-work