Stub [[SomeClazz alloc] init] does not work, but the accepted answer says that it should work

My tested function is very simple:

@implementation MyHandler ... -(void) processData { DataService *service = [[DataService alloc] init]; NSDictionary *data = [service getData]; [self handleData:data]; } @end 

I use OCMock 3 before unit test.

I need to [[DataService alloc] init] in order to return the scoffed instance , I tried the answer from this question (which is the 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 set a breakpoint in the function under test, I am sure that [service getData] is called when unit test starts, but my test code (OCMVerify) described above fails. What for?

Is it because the test function is not using my mocked DataService ? But the answer accepted in this question says that it should work. Now I'm confused ...

I want to know how to [[SomeClazz alloc] init] to return a mocking instance with OCMock?

+2
ios objective-c unit-testing ocmock
source share
1 answer

You cannot make fun of init because it is implemented by the mock object itself. The reason that the mock init works in the answer related to you is because it is a custom initialization method . If you do not want to use dependency injection, you will have to write your own init method for the DataService , which you can make fun of.

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 your MyHandler implementation to call this initForTest :

 @implementation MyHandler ... -(void) processData { DataService *service = [[DataService alloc] initForTest]; NSDictionary *data = [service getData]; [self handleData:data]; } @end 

Finally, upgrade your test to the initForTest stub:

 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]); 

You cannot rename initForTest , until it is called init .

0
source share

All Articles