stub [[SomeClazz alloc] init] not work but accepted answer says it should work

天大地大妈咪最大 提交于 2019-12-21 20:17:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!