1

I need to test an instance variable in Objective C.

I have this snippet in myViewController.m

@implementation myViewController
{
NSView *myView;
}

I need to add a test in myViewControllerTest.mm that tests a case when myView.window happens to be nil

-(void) myTest 
{
// 1. assert condition 1 is true
// 2. mock myView.window and set it to nil OR set myView.window directly to nil
// 3. assert condition 1 is false
}

I'd like to know the best approach to achieve step 2 in the test. Approaches I tried:

  • Add an explicit setter - (void)setMyView:(NSView*)myView just for the unit test purpose and use that in myTest. I have a feeling that this is not a good way.
  • make myView as a property and put it in myViewController.h so that I'll have a setter without explicitly defining one.
  • Unsuccessful attempt at mocking using OCMock. (need to explore further)

Please suggest what the best approach is and what are the pros/cons of them. Thanks !

Edit : Answer I ended up using in my test file.

[myViewController setValue:nil forKeyPath:@"myViewControl.window"];

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/BasicPrinciples.html#//apple_ref/doc/uid/20002170-BAJEAIEE

zazky
  • 45
  • 1
  • 6

1 Answers1

4

You can add setter only for testing in your test file myViewControllerTest.mm

This has no effect to your production code.

like below using Extension

// Write this in test file.
@interface MyViewController(Test)
- (void)setMyView:(NSView *)myView;
@end

or just use valueForKey: to get private field.

-(void) myTest 
{
  id myViewController = ...;
  NSView *myView = [myViewController valueForKey:@"myView"];
  myView.window = nil;
  // ...
}
pompopo
  • 929
  • 5
  • 10