I've been having a lot of trouble trying to do some testing on my classes that use AudioContext. I believe a lot of my frustration stems from not having a good understanding of mocking functions and possibly how tests are executed.
I'm trying to test one class that takes AudioContext, however I keep getting this error when I run a test:
When using TypeScript files:
TypeError: (window.AudioContext || window.webkitAudioContext) is not a constructor
This error happens inside the app.ts file. When I run a test does it have to resolve or execute all of it's dependencies?
When using JavaScript files this error occurs in the test file: ReferenceError: AudioContext is not defined
Right now, I assume I have to make a mock AudioContext. How do I even go about knowing all the methods on AudioContext to begin to manually mock it?
Here's a simplified version of my sheets. I will provide TS and JS versions of both:
TypeScript File Versions:
// 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 File Versions:
// 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;
Test file that brings up the errors in bold that I mentioned earlier:
// 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);
})
Update: I have the code working for plain JS files now. I added an empty AudioContext mock to my tests.
// 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 {}
});
Since my project is written in TypeScript, I tried adding the mock to my project, but I still get the error from above "TypeError: (window.AudioContext || window.webkitAudioContext) is not a constructor".
Thanks :).
Old post, but I thought I would share how I handled the typescript error. To keep the leverage of Typescript and types, I just added the webkitAudioContext
to the defined Window
typing. My code looks like:
declare var window: {
webkitAudioContext: typeof AudioContext;
} & Window & typeof globalThis;
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
That essentially tells typescript to union Window & typeof globalThis
with the new webkitAudioContext
property.
As far as the ReferenceError: AudioContext is not defined error, that is most likely because AudioContext
is not mocked (like you said – this is also the question I was searching for when I stumbled across your post). I know jest uses jsdom to mock the dom. jsdom currently doesn't support AudioContext mocks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With