模拟 AVCaptureDeviceInput 用于测试

Jon*_*gel 5 testing automated-tests protocols mocking swift

我正在尝试测试我的应用程序如何响应不同的 AVFoundation 配置。我正在使用 WWDC 视频“可测试性工程”中描述的技术。

我创建了一个协议来表示我的应用程序使用的各个部分AVCaptureDevice

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
}
Run Code Online (Sandbox Code Playgroud)

我有一个符合我的协议的扩展AVCaptureDevice

extension AVCaptureDevice: AVCaptureDeviceProperties {
   //Don't need anything because AVCaptureDevice already has implementations of all the properties and functions I use.
}
Run Code Online (Sandbox Code Playgroud)

我现在可以为自己创建一个对象,在其中可以为不同的测试用例配置所有属性。效果很好!

但是,我需要更进一步并获取一个模拟AVCaptureDeviceInput对象。该对象只有一个需要 a 的初始化程序AVCaptureDevice,但我希望能够使用我的协议类型进行模拟初始化。到目前为止我有这个:

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

但是,我永远不会使用符合我的协议的模拟对象成功初始化。我该如何解决这个问题以便我可以测试?