Reputation: 803
I'm looking for a way to set up navigator.serviceWorker to unit test my service worker. My current JSDOM setup looks like this:
import { JSDOM } from 'jsdom';
const dom = new JSDOM('<!DOCTYPE html><html><head></head><body></body></html>');
global.window = dom.window;
global.document = dom.window.document;
Object.keys(global.window).forEach(property => {
if (typeof global[property] === 'undefined') {
global[property] = global.window[property];
}
});
global.navigator = {
userAgent: 'node.js'
};
I've already tried commenting out global.navigator = ...
for global.navigator = global.window.navigator
. However, the following console.log(global.navigator.serviceWorker)
and console.log(navigator.serviceWorker)
both return undefined
in my unit test:
describe('Service Worker', () => {
it('should register a service worker and cache files on install', () => {
console.log(navigator.serviceWorker); // undefined
// navigator.serviceWorker.register() // not used yet since undefined
});
});
Upvotes: 4
Views: 3489
Reputation: 539
Use Object.defineProperty
method to create a new serviceWorker
property:
Object.defineProperty(global.navigator, 'serviceWorker', {
value: {
register: jest.fn() // Choose your favourite mocking library
}
});
Defining register
method as a mock function, will allow you to spy the calls made to that function and also return a promise that can be resolve or reject.
import sw from './service-worker';
describe('Service worker registration', () => {
it('call navigator.serviceWorker.register with the right URL', () => {
expect(navigator.serviceWorker.register).toHaveBeenCalledWith('/service-worker.js');
});
});
Upvotes: 10