我正在开发JavaScript库(https://github.com/yvesgurcan/web-midi-player)以启用Web应用程序中的MIDI播放。该库依靠Web Audio API来创建一种播放这些MIDI文件(https://github.com/yvesgurcan/web-midi-player/blob/test/src/MidiPlayer.js#L50)的方式。但是,我无法使用Jest(https://github.com/yvesgurcan/web-midi-player/blob/test/tests/midiPlayer.js)创建有意义的单元测试,因为这些测试无法访问window
对象,尤其是window.AudioContext
对象。结果,运行依赖于AudioContext
的应用程序代码将引发与以下事实有关的错误:该对象不存在,并且我实际上无法在库中测试太多内容。
我尝试了以下软件包来解决我的问题:jsdom
,jsdom-global
以及web-audio-test-api
,但似乎没有一个注入环境中的AudioContext
。
我认为这里的解决方案是存根/模拟AudioContext
,但这听起来不是固态单元测试的好解决方案。
您对测试Web Audio API有何建议?存根是唯一可行的解决方案吗?
我认为这取决于您要测试的内容。既然您使用的是Jest,我想您只是对测试自己代码的正确性感兴趣。在那种情况下,我建议完全模拟Web Audio API。这不是您责任的一部分,您可以假设它按应有的方式发挥作用。您唯一需要测试的就是您的代码是否正在进行预期的调用。
模拟像AudioContext构造函数这样的全局可用变量总是有些棘手,但是您可以允许将AudioContext作为可选参数传递到MidiPlayer
类中。这将使测试变得容易一些,并且还允许您的库的用户携带自己的AudioContext。
我想到这样的东西:
class MidiPlayer {
constructor({
// ... the other options ...
context = new AudioContext()
}) {
// ...
}
}
然后在测试中,您可以简单地用伪造的MidiPlayer
实例化AudioContext
。
const fakeAudioContext = {
currentTime: 3,
// ... and all the other things your code uses ...
};
const midiPlayer = new MidiPlayer({ context: fakeAudioContext });
我最近回答了一个similar question related to Tone.js,可能会有所帮助。基本思想是相同的。
[如果要在浏览器中测试您的库是否与Web Audio API配合良好,我建议使用Karma之类的测试运行程序。它在真实的浏览器中执行测试,因此可以使用所有浏览器API。