Mock AVCaptureDeviceInput for testing
Asked Answered
Q

0

6

I'm trying to test how my App responds to different AVFoundation configurations. I'm using the techniques described in the WWDC video 'Engineering for Testability.'

I created a protocol to represent the pieces of an AVCaptureDevice that my app uses.

public protocol AVCaptureDeviceProperties: class {
    //MARK: Properties I use and need to test
    var position: AVCaptureDevice.Position { get }
    var focusMode: AVCaptureDevice.FocusMode { get set }
    var exposureMode: AVCaptureDevice.ExposureMode { get set }
    var whiteBalanceMode: AVCaptureDevice.WhiteBalanceMode { get set }
    //MARK: Functions I use use and need to test
    func lockForConfiguration() throws
    func unlockForConfiguration()
    func isFocusModeSupported(_ focusMode: AVCaptureDevice.FocusMode) -> Bool
    func isExposureModeSupported(_ exposureMode: AVCaptureDevice.ExposureMode) -> Bool
    func isWhiteBalanceModeSupported(_ whiteBalanceMode: AVCaptureDevice.WhiteBalanceMode) -> Bool
}

I have an extension that makes AVCaptureDevice conform to my protocol.

extension AVCaptureDevice: AVCaptureDeviceProperties {
   //Don't need anything because AVCaptureDevice already has implementations of all the properties and functions I use.
}

I can now make an object for myself where I can configure all the properties for different test cases. Works great!

However, I need to take it another step further and get a mock AVCaptureDeviceInput object. This object only has one initializer that takes a AVCaptureDevice but I want to be able to mock initialize with my protocol type. So far I have this:

extension AVCaptureDeviceInput {
    convenience init?(device: AVCaptureDeviceProperties) throws {
        guard let downcast = device as? AVCaptureDevice else {
            return nil
        }
        try self.init(device: downcast)
    }
}

However, I will never get a successful initialization with a mock object that conforms to my protocol. How to I solve this problem so I can test?

Quadrivalent answered 7/5, 2019 at 16:48 Comment(4)
Did you figure this out?Machicolation
Do you find any solution?Lagan
@IzabellaMelo never did. However, this method of mocking is still valid IMO. There are just edge cases where it will not work.Quadrivalent
@JonVogel I tried to use the swizzle method to mock it but it did not work (#78584208). Testing code with AVFoundation APIs is really hard :(Lagan

© 2022 - 2024 — McMap. All rights reserved.