在单元测试中使用 AudioContext

Using AudioContext in unit tests

我正在开发一个 JavaScript 库 (https://github.com/yvesgurcan/web-midi-player) to enable MIDI playback in a web application. The library relies on the Web Audio API to create a way to play these MIDI files (https://github.com/yvesgurcan/web-midi-player/blob/test/src/MidiPlayer.js#L50). However, I am having trouble creating meaningful unit tests with Jest (https://github.com/yvesgurcan/web-midi-player/blob/test/tests/midiPlayer.js),因为这些测试无法访问 window 对象,尤其是 window.AudioContext。结果,运行 我依赖于 AudioContext 的应用程序代码抛出与该对象不存在相关的错误,我实际上无法测试库中的很多东西。

我尝试了以下软件包来解决我的问题:jsdomjsdom-global 以及 web-audio-test-api,但其中 none 似乎注入了 AudioContext 在环境中。

我认为这里的解决方案是 stub/mock AudioContext 但这听起来不像是可靠的单元测试的好解决方案。

大家有什么建议来测试网络音频 API?存根是这里唯一可行的解​​决方案吗?

我认为这在一定程度上取决于您要测试的内容。由于您使用的是 Jest,我想您只是对测试自己代码的正确性感兴趣。在那种情况下,我建议完全模拟网络音频 API。这不是您的责任的一部分,您可以假设它按应有的方式工作。您唯一需要测试的是您的代码是否进行了预期的调用。

模拟全局可用的变量,如 AudioContext 构造函数总是有点棘手,但您可以允许将 AudioContext 作为可选参数传递到您的 MidiPlayer class 中。这将使测试更容易一些,并且还允许您的图书馆的用户带来他们自己的 AudioContext。

我想到了这样的事情:

class MidiPlayer {

    constructor({
        // ... the other options ...
        context = new AudioContext()
    }) {
        // ...
    }

}

在测试中,您可以简单地用一个假 AudioContext.

实例化 MidiPlayer
const fakeAudioContext = {
    currentTime: 3,
    // ... and all the other things your code uses ...
};
const midiPlayer = new MidiPlayer({ context: fakeAudioContext });

我最近回答了一个 ,这可能会有帮助。基本思路是一样的。

如果您想在浏览器中测试您的库是否与 Web Audio API 兼容,我建议您使用像 Karma 这样的测试运行器。它在真实浏览器中执行测试,因此可以使用所有浏览器 APIs.