Testing Worker in Jest
Hi,
I'm trying to test my worker inside a Vue.js project. I load the worker inside my component using the worker-plugin (I also tried loading my Worker using Webpack worker-loader, unfortunately it doesn't provide a compatible interface and I had to mock the worker in that case)
const worker = new Worker('@/utils.worker.js', { type: 'module' });
But when I run my tests with Jest I get
console.error node_modules/jsdom-worker/dist/jsdom-worker.js:1
TypeError: Only absolute URLs are supported
...
I’m running into this issue as well with:
const worker = new Worker(new URL('../utils/worker.ts', import.meta.url))
Here, in a development environment, the call to new URL('…', import.meta.url) resolves to a URL with a file: scheme which doesn’t work (supposedly because the scheme needs to be either either http: or https:).
Mocking the worker is possibly an option, but I think I can’t turn my worker file into a module because Firefox doesn’t support it, yet (see bug https://bugzilla.mozilla.org/show_bug.cgi?id=1247687; for what it’s worth, this seems to very much be in active development). I’m not sure how to proceed now.
I’m now experimenting with a createWorker utility function which I use in my code instead of calling new Worker directly. This workaround is pretty unsatisfying because a lot of my application’s code ends up using this and so I would need to mock the createWorker utility in each of them.
createWorker.ts:
export function createWorker(url, onMessageHandler) {
const worker = new Worker(url)
worker.onmessage = onMessageHandler
return worker
}
In my test:
jest.mock('@/utils/createWorker', () => {
const { readFileSync } = require('fs')
const { resolve } = require('path')
const code = readFileSync(resolve(__dirname, '../utils/worker.js'), 'utf8')
const workerUrl = URL.createObjectURL(new global.Blob([code]))
return {
__esModule: true,
createWorker(_url, onMessageHandler) {
const worker = new global.Worker(workerUrl)
worker.onmessage = onMessageHandler
return worker
},
}
})