I have a test that needs to use navigator.mediaDevices
but I cannot get any mocks to work correctly.
I am using create-react-app
.
Here is my test:
import getConnectedDevices from "./getConnectedDevices";
describe("getConnectedDevices", () => {
it("Should work", () => {
console.log(navigator); // Navigator {}
console.log(navigator.mediaDevices); // undefined
});
});
I have tried adding a mock as it states here in the jest documentation
// tests/navigator.mock
Object.defineProperty(window, "navigator", {
writable: true,
value: {
mediaDevices: {
enumerateDevices: jest.fn(),
},
},
});
import "../../tests/navigator.mock"; // <- Mock added
import getConnectedDevices from "./getConnectedDevices";
describe("getConnectedDevices", () => {
it("Should work", () => {
console.log(navigator); // Navigator {}
console.log(navigator.mediaDevices); // undefined
});
});
I have also tried Initializing the test environment according to the create-react-app docs.
// src/setupTests.ts
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom";
const navigatorMock = {
mediaDevices: {
enumerateDevices: jest.fn(),
},
};
global.navigator = navigatorMock;
What am I doing wrong?
It appears that because there already is a navigator
object, it's not possible to re-assign it.
Thanks to this stackoverflow answer, you mock the object within the navigator
and assign it to the existing navigator object.
// src/setupTests.ts
const mediaDevicesMock = {
enumerateDevices: jest.fn(),
};
global.navigator.mediaDevices = mediaDevicesMock; // here
Note: This will throw a TSC error Cannot assign to 'mediaDevices' because it is a read-only property.ts(2540)
. Still trying to figure that one out.