I'm trying to write tests for a tap-to-focus method I've implemented for a AVCaptureVideoPreviewLayer. I want to use a mock AVCaptureDevice in order to pass the various conditions and then to make sure the expected methods are called to handle the actual focusing. Below is the code I'm using.
NSArray *devices = [AVCaptureDevice devices];
for (AVCaptureDevice *device in devices)
{
if ([device hasMediaType:AVMediaTypeVideo])
{
if ([device position] == AVCaptureDevicePositionBack)
{
CGPoint point = CGPointMake(focus_y, 1-focus_x);
if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [device lockForConfiguration:&error])
{
...
This is the test code I have so far:
id deviceMock = [OCMockObject niceMockForClass:[AVCaptureDevice class]];
[[[deviceMock stub] andReturnValue:@YES] hasMediaType:AVMediaTypeVideo];
[(AVCaptureDevice*)[[deviceMock stub] andReturnValue:@(AVCaptureDevicePositionBack)] position];
[[[deviceMock stub] andReturnValue:@YES] isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus];
[[[deviceMock stub] andReturnValue:@YES] lockForConfiguration:nil];
[[deviceMock expect] setFocusPointOfInterest:CGPointZero];
[[deviceMock expect] setFocusMode:AVCaptureFocusModeAutoFocus];
[[deviceMock expect] unlockForConfiguration];
[self waitForCompletion:0.55]; //Wait for UI animation
[deviceMock verify]
I'd like to perform three tests:
- [AVCaptureDevice devices] returns 0 devices and nothing happens
- [AVCaptureDevice devices] returns an incompatible device and nothing happens
- [AVCaptureDevice devices] returns a compatible device and the above test code passes
So I guess my question boils down to is there an easy way to stub and return [AVCaptureDevice devices] class method? Or is it safe to assume that there can only be one AVCaptureDevice on an iPhone/iPad that passes the above conditions so I could store the device as a property and rewrite the method I'm testing so that I can inject the mock AVCaptureDevice?