3

I'm trying to mock UIImagePickerController to test method from ViewController (written in Swift):

var imagePicker: UIImagePickerController!

...

func choosePhoto() {
    imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .PhotoLibrary
    self.presentViewController(imagePicker, animated: true, completion: nil)
}

and the test class (written in Objective-C):

Interface:

@property (nonatomic, strong) ViewController *viewController;

Implementation:

- (void)setUp {
    [super setUp];

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UINavigationController *navigationController = [storyboard instantiateInitialViewController];
    self.viewController = (ViewController *)[navigationController visibleViewController];
    self.viewController.view;
}

....

- (void)testPicker {
    id mockPicker = [OCMockObject mockForClass:[UIImagePickerController class]];
    self.viewController.imagePicker = mockPicker;

    [[mockPicker expect] setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
    [[(id)self.viewController expect] presentViewController:mockPicker animated:YES completion:nil];

    [self.viewController choosePhoto];

    [mockPicker verify];
}

The test fails, because:

OCMockObject(UIImagePickerController): expected method was not invoked: setSourceType:0

and

failed: caught "NSInvalidArgumentException", "-[MyApp.ViewController expect]: unrecognized selector sent to instance 0x....

Can anyone help me with this?

Many thanks.

jonaszmclaren
  • 2,459
  • 20
  • 30

1 Answers1

1

So, to use the expect method from OCMock, you have to have a mock of the object that is expecting a method call. In this case, you need to have a mock for self.myViewController - the ViewController class you're using doesn't have an expect method, so its getting confused. The fact that you're casting the VC to an id is masking the issue.

bplattenburg
  • 623
  • 1
  • 8
  • 33
  • 1
    Thanks for your answer. The mock for picker is working, but not with view controller. I did some experimentation and it turned out that it is a limitation of Swift language, because in Objective-C it verifies, that some other method was called in test method, but in Swift it is not working. – jonaszmclaren Aug 26 '15 at 07:35
  • Interesting - I haven't done too much with OCMock and Swift yet, so I didn't even consider that. – bplattenburg Aug 27 '15 at 15:58
  • @jonaszmclaren There is a lot better way to mock objects in Swift. don't need any third party libraries like OCMock – Ali Riahipour Aug 16 '16 at 05:44