代码之家  ›  专栏  ›  技术社区  ›  Udders

jest spyOn navigator.media设备

  •  0
  • Udders  · 技术社区  · 3 年前

    我目前正在编写一个小型库,以帮助连接到媒体设备,如果我能对库进行单元测试,那就太好了,我的打字库中有一个函数,看起来像这样,

    static connectAudioDevice(device?: InputDeviceInfo) : Promise<MediaStream> {
        return new Promise<MediaStream>((resolve, reject) => {
            navigator.mediaDevices.getUserMedia({audio: true})
                .then(stream => {
                    resolve(stream);
                })
                .catch(error => {
                    resolve(error);
                })
        })
    }
    

    我想用 jest.spyOn 嘲笑 getUserMedia 这可能吗?类似于,

    import devices from '@/assets/lib/devices.ts';
    
    test('Resolves with valid audio mediaStream', () => {
    
        const audioStream = {};
        let promise = devices.connectAudioDevice();
    
        jest.spyOn(window.navigator.mediaDevices, 'getUserMedia', promise);
    
    })
    

    但我得到了错误:

    无法对基元值进行spyOn;未定义给定

    有人能帮我吗?

    0 回复  |  直到 3 年前
        1
  •  6
  •   Lin Du    3 年前

    这个 navigator.mediaDevices 不是由JSDOM实现的。所以 window.navigator.mediaDevices undefined 这就是你出错的原因。看看 Mocking methods which are not implemented in JSDOM .

    解决方案是:

    device.ts :

    export default class Devices {
      public static connectAudioDevice(device?: InputDeviceInfo): Promise<MediaStream> {
        return new Promise<MediaStream>((resolve, reject) => {
          navigator.mediaDevices
            .getUserMedia({ audio: true })
            .then((stream) => {
              resolve(stream);
            })
            .catch((error) => {
              resolve(error);
            });
        });
      }
    }
    

    device.test.ts :

    import devices from './deivce';
    
    describe('65112057', () => {
      test('Resolves with valid audio mediaStream', async () => {
        const mockMediaDevices = {
          getUserMedia: jest.fn().mockResolvedValueOnce('fake data' as any),
        };
        Object.defineProperty(window.navigator, 'mediaDevices', {
          writable: true,
          value: mockMediaDevices,
        });
        const actual = await devices.connectAudioDevice();
        expect(actual).toBe('fake data');
        expect(mockMediaDevices.getUserMedia).toBeCalledWith({ audio: true });
      });
    });
    

    单元测试结果:

    
     PASS  src/stackoverflow/65112057/device.test.ts
      65112057
        ✓ Resolves with valid audio mediaStream (7ms)
    
    -----------|----------|----------|----------|----------|-------------------|
    File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    -----------|----------|----------|----------|----------|-------------------|
    All files  |       80 |      100 |       75 |       80 |                   |
     deivce.ts |       80 |      100 |       75 |       80 |                10 |
    -----------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        4.994s, estimated 13s