用Jest,AudioContext测试和模拟

时间:2019-04-10 15:18:14

标签: javascript typescript unit-testing testing jestjs

尝试对使用AudioContext的类进行一些测试时遇到了很多麻烦。我相信,我的许多挫败感源于对模拟功能以及测试的执行方式不甚了解。

我正在尝试测试一个采用AudioContext的类,但是在运行测试时却不断收到此错误:

使用TypeScript文件时: TypeError:(window.AudioContext || window.webkitAudioContext)不是构造函数
此错误发生在app.ts文件内。当我运行测试时,它是否必须解析或执行所有依赖项?

使用JavaScript文件时,该错误会在测试文件中发生: ReferenceError:未定义AudioContext

现在,我假设我必须制作一个模拟AudioContext。我什至如何知道AudioContext上的所有方法来开始手动模拟它?

这是我的床单的简化版。我将同时提供TS和JS版本:

TypeScript文件版本:

// app.ts
import Sampler from './Sampler';
const audioContext: AudioContext = new (window.AudioContext || window.webkitAudioContext)();
const sampler: Sampler = new Sampler(audioContext);


// Sampler.ts
export default class Sampler{
    private audioContext: AudioContext;

    constructor(audioContext: AudioContext){
        this.audioContext = audioContext;      
    }
 }

JS文件版本:

// app.js
const Sampler = require('./Sampler');
const audioContext =  new (window.AudioContext || window.webkitAudioContext)();
const sampler = new Sampler(audioContext);

// Sampler.js
class Sampler{
    constructor(audioContext){
        this.audioContext = audioContext;   
    }
}
module.exports = Sampler;

测试文件以粗体显示了我之前提到的错误:

// sampler.test.ts

import Sampler from './Sampler';
// Uncomment line below if you're using plain JS and not TS
// const Sampler = require('./Sampler');

test('Test test', () => {
  const audioContext = new AudioContext();
  const s = new Sampler(audioContext);
})

更新: 我现在有适用于普通JS文件的代码。我在测试中添加了一个空的AudioContext模拟。

// sampler.test.js
const Sampler = require('./Sampler');
require('./__mocks__/app');


test('Testing Mock AudioContext', () => {
    const audioContext = new AudioContext();
    const s = new Sampler(audioContext);
})


// __mocks__/app.js
window.AudioContext = jest.fn().mockImplementation(() => {
    return {}
});

由于我的项目是用TypeScript编写的,因此我尝试将模拟添加到我的项目中,但仍然收到“ TypeError:(window.AudioContext || window.webkitAudioContext)不是构造函数”的错误。

谢谢:)。

2 个答案:

答案 0 :(得分:1)

旧帖子,但我想我会分享我如何处理打字稿错误。为了保持 Typescript 和类型的优势,我只是在定义的 webkitAudioContext 类型中添加了 Window。我的代码看起来像:

declare var window: {
  webkitAudioContext: typeof AudioContext;
} & Window & typeof globalThis;

const audioContext = new (window.AudioContext || window.webkitAudioContext)();

这实质上是告诉打字稿将 Window & typeof globalThis 与新的 webkitAudioContext 属性联合起来。

至于 ReferenceError: AudioContext is not defined 错误,这很可能是因为 AudioContext 没有被模拟(就像你说的 - 这也是我在什么时候搜索的问题我偶然发现了你的帖子)。我知道 jest 使用 jsdom 来模拟 dom。 jsdom currently doesn't support AudioContext mocks

答案 1 :(得分:0)

您可以通过将window指定为“ any”类型来解决此问题,即

const audioContext: AudioContext = 
 new (AudioContext || (window as any).webkitAudioContext)();

here所述。

请注意,我认为您不需要通过代码中的窗口访问AudioContext,因为它应该可用。