Leem.fin
Leem.fin

Reputation: 42602

use mocked object created in initializer

I have a Worker class, its header:

@interface Worker : NSObject {
  // instance variable `task`
  MyTask *task;
}
@end

its initialiser method is like this:

@implementation Worker

-(id)initWithName:(NSString*)name{
  self = [super init];
  if (self) {
    // I need to use mocked task in my test case
    task = [[MyTask alloc] init];
    ...
    ...
  }
  return self
}

-(void)doWork{
  [task start];
}

I want to unit test this class, I am using OCMock library to do the mock. I know I can create a mocked task by:

id mockedTask = OCMClassMock([MyTask class]);

But, how can I inject this mocked task into my Worker instance in test case ? I mean task is created in initialiser method, when I create a Worker instance in my test class:

-(void)setup{
  // how to inject the mocked task in to this workerUnderTest
  Worker *workerToTest = [[Worker alloc] initWithName:@"John"];
}

I need the mocked task to be used in test. How can I achieve it?

==== My Test case with @iSashok's answer (it doesn't work) ====

@interface WorkerTestCase : XCTestCase 
@end

@implementation WorkerTestCase{
  Worker *workerToTest;
  id mockedTask;
}
- (void)setUp {
  [super setUp];
  workerToTest = [[Worker alloc] initWithName:@"John"];

  mockedTask = OCMClassMock([MyTask class]);
  OCMStub([workerToTest task]).andReturn(mockedTask);
}

-(void) testDoWork{
 [workerToTest doWork];
 // it fails. method is not invoked!
 OCMVerify([mockedTask start]);
}
...
@end

As you see above, my test case fails, it complains that there is no invokation on mockedTask object. But when I set breakpoints to real class implementation, the [task start] is invoked, it indicates the mockedTask is not injected successfully.

Upvotes: 0

Views: 170

Answers (1)

iSashok
iSashok

Reputation: 2446

You can inject it using OCMStub() like below and you need declare task ivar as a property

@interface Worker : NSObject 
@property(nonatomic,strong)MyTask *task;
@end

//

id mockedTask = OCMClassMock([MyTask class]);
OCMStub([workerToTest task]).andReturn(mockedTask);

You method will look like

-(void)setup{
  // how to inject the mocked task in to this workerUnderTest
  Worker *workerToTest = [[Worker alloc] initWithName:@"John"];

  id mockedTask = OCMClassMock([MyTask class]);
  OCMStub([workerToTest task]).andReturn(mockedTask);
}

Upvotes: 0

Related Questions