首页 > 解决方案 > AVPlayerItem 状态观察者 - 单元测试状态更改

问题描述

有没有人对 swift 中的单元测试键值观察逻辑有任何参考?我想在我的单元测试中模拟 AVPlayerItem 的状态更改,以确认触发了预期的逻辑。为简单起见,这是我到目前为止所拥有的:

观察提供的 playerItem 状态的函数

public func observePlayerItemStatus(playerItemToObserve: AVPlayerItem) -> NSKeyValueObservation {
    let observerToken = playerItemToObserve.observe(\.status, options: [.new, .old], changeHandler: { (playerItemToObserve, _) in
        switch playerItemToObserve.status {
        case .failed:
            // failed logic
        case .readyToPlay:
            // ready to play logic
        default:
            // default logic
        }
    })

    return observerToken
}

我创建了一个模拟类 MockAVPlayerItem

class MockAVPlayerItem: AVPlayerItem {
    var mockStatus: AVPlayerItem.Status = .unknown
    public override var status: AVPlayerItem.Status {
        get { return mockStatus }
        set { self.mockStatus = newValue }
    }
}

我尝试触发状态代码更改的单元测试执行以下操作:

func test_readyToPlayIsTriggered() {
   let url = URL(string: "https://www.rmp-streaming.com/media/big-buck-bunny-360p.mp4")!
   let mockPlayerItem = MockPlayerItem(url: url)
   let statusToken = observePlayerItemStatus(playerItemToObserve: mockPlayerItem)
   mockPlayerItem.status = .readyToPlay

... some assertion that ready to play was called ....
}

当我运行应用程序时,逻辑本身会起作用,但是我的单元测试无法触发我的观察者。我采用了类似的模拟方法,AVPlayer.timeControlStatus效果很好,但由于某种原因AVPlayerItem.status表现不一样。

标签: swiftunit-testing

解决方案


在我的模拟中使用willChangeValueanddidChangeValue解决了我的问题。观察者现在按预期触发。

class MockAVPlayerItem: AVPlayerItem {
    var mockStatus: AVPlayerItem.Status = .unknown
    public override var status: AVPlayerItem.Status {
        get { return mockStatus }
        set {
            willChangeValue(for: \.status)
            self.mockStatus = newValue
            didChangeValue(for: \.status)
        }
    }
}


推荐阅读