Test wether a Method get called

Discussion of the OCMock framework. If you have patches we would prefer you to send them to the mailing list, but attaching them to a topic is possible, too.

Test wether a Method get called

Postby Togo » 19 Dec 2012, 00:50

Hi,

i'm struggling with checking wether a method get called or not:

In my controller i have the method, which should call a method in the AppDelegate:
- (IBAction) startButtonClicked:(id)sender {
AppDelegate *app = (AppDelegate*) [[NSApplication sharedApplication] delegate];
[app startCreateNewAppModuleClicked];
}


here is my AppDelegate method:
- (void) startCreateNewAppModuleClicked {
NSLog(@"Test");
}


and here is the test i wrote:
- (void)setUp
{
[super setUp];

appDelegateMock = [OCMockObject mockForClass:AppDelegate.class];
createNewAppWindowControllerMock = [OCMockObject mockForClass:CreateNewAppWindowController.class];
}

- (void)tearDown
{

[super tearDown];
}

- (void) testCreateNewAppModuleWhenStartButtonClicked {
[[appDelegateMock expect] startCreateNewAppModuleClicked];
[createNewAppWindowControllerMock startButtonClicked:nil];
[appDelegateMock verify];
}


I tried different approaches but never get the test passed. Either i get a "Wrong method invoked" Fail or a "Method not called" Fail.
Thanks

tobi
Togo
 

Re: Test wether a Method get called

Postby drewag » 19 Dec 2012, 04:59

The problem you are having is because you are mocking both objects. A mock object will not do anything when you call a method on it (unless it is a partial mock). You should only be mocking the object that you want to verify the method call for. In your case you should create a real CreateNewAppWindowController as that is the object you are testing. The general rule is that you should use the real object for the class you are testing and mock objects for everything else possible.
drewag
 

Re: Test wether a Method get called

Postby Togo » 19 Dec 2012, 17:17

drewag wrote:The problem you are having is because you are mocking both objects. A mock object will not do anything when you call a method on it (unless it is a partial mock). You should only be mocking the object that you want to verify the method call for. In your case you should create a real CreateNewAppWindowController as that is the object you are testing. The general rule is that you should use the real object for the class you are testing and mock objects for everything else possible.


Thanks for your answer. I tried this but getting still the fail message:

Code: Select all
error: testCreateNewAppModuleWhenStartButtonClicked (CreateNewAppWindowControllerTests) failed: OCMockObject[AppDelegate]: expected method was not invoked: startCreateNewAppModuleClicked


I'm a little bit confused because i see the log message test. So the method get definitely called!

Here is my new testcode:
Code: Select all
- (void)setUp
{
  [super setUp];
  createNewAppWindowController = [[CreateNewAppWindowController alloc] init];
  appDelegateMock = [OCMockObject mockForClass:AppDelegate.class];
}

- (void)tearDown
{
  // Tear-down code here.
 
  [super tearDown];
}

- (void) testCreateNewAppModuleWhenStartButtonClicked {
  [[appDelegateMock expect] startCreateNewAppModuleClicked];
  [createNewAppWindowController startButtonClicked:nil];
  [appDelegateMock verify];
}
Togo
 

Re: Test wether a Method get called

Postby drewag » 20 Dec 2012, 08:31

The problem now is that you are creating a new version of your app delegate completely separate from the existing app delegate. Then when the function is called it gets the app delegate through the shared application which will be the real delegate and not the mock one. What you should do is create a "partial" mock like so:

Code: Select all
appDelegateMock = [OCMockObject partialMockForObject:[[NSApplication sharedApplication] delegate]];


This will wrap the existing appDelegate in a mock and you can create expectations on that.
drewag
 


Return to OCMock