如何为 Jest 模拟导航器 mediaDevices

How to mock navigator mediaDevices for Jest

我有一个测试需要使用 navigator.mediaDevices,但我无法让任何模拟正常工作。

我正在使用 create-react-app

这是我的测试:

import getConnectedDevices from "./getConnectedDevices";

describe("getConnectedDevices", () => {
  it("Should work", () => {
    console.log(navigator);              // Navigator {}
    console.log(navigator.mediaDevices); // undefined
  });
});

我已经尝试添加一个模拟,因为它指出 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
  });
});

我也根据 create-react-app 文档尝试了 Initializing the test environment

// 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;

我做错了什么?

似乎因为已经有一个 navigator 对象,所以无法重新分配它。

感谢 ,您在 navigator 中模拟对象并将其分配给现有的导航器对象。

// src/setupTests.ts

const mediaDevicesMock = {
  enumerateDevices: jest.fn(),
};

global.navigator.mediaDevices = mediaDevicesMock; // here

注意:这将引发 TSC 错误 Cannot assign to 'mediaDevices' because it is a read-only property.ts(2540)。仍在尝试解决这个问题。

我是用打字稿做的:

const mockGetUserMedia = jest.fn(async () => {
    return new Promise<void>(resolve => {
        resolve()
    })
})

Object.defineProperty(global.navigator, 'mediaDevices', {
    value: {
        getUserMedia: mockGetUserMedia,
    },
})