Jest 如何模拟全局变量 navigator.onLine。

3

如何在React中使用jest模拟global.navigator.onLine

我的jest版本是最新的24.9.0

我尝试过以下方法:

global.navigator = {
  onLine: false,
}

并使用jest.fn().mockImplementation(() => ({onLine: false}))

它们似乎仍然返回true,用于navigator.onLine

1个回答

18
你可以使用jest.spyOn(object, methodName, accessType?)方法来模拟只读属性onLine的值,其中object为要模拟的对象,methodName为要模拟的方法名,accessType(可选)为要模拟的属性类型,可以是'get'或'set'(如果你想模拟getter或setter)。此外,这与UI库reactjs无关。

从Jest 22.1.0+开始,jest.spyOn方法有一个可选的第三个参数accessType,可以是'get'或'set'。当你想要监视getter或setter时,这证明是有用的。

例如:

index.ts:

export function main() {
  if (navigator.onLine) {
    console.log('online');
  } else {
    console.log('offline');
  }
}

index.spec.ts:

import { main } from './';

describe('main', () => {
  beforeEach(() => {
    jest.restoreAllMocks();
  });
  test('should log "online"', () => {
    const logSpy = jest.spyOn(console, 'log');
    jest.spyOn(navigator, 'onLine', 'get').mockReturnValueOnce(true);
    main();
    expect(logSpy).toBeCalledWith('online');
  });

  test('should log "offline"', () => {
    const logSpy = jest.spyOn(console, 'log');
    jest.spyOn(navigator, 'onLine', 'get').mockReturnValueOnce(false);
    main();
    expect(logSpy).toBeCalledWith('offline');
  });
});

100%覆盖率的单元测试结果:

 PASS  src/stackoverflow/58603653/index.spec.ts (10.016s)
  main
    ✓ should log "online" (14ms)
    ✓ should log "offline" (7ms)

  console.log node_modules/jest-mock/build/index.js:860
    online

  console.log node_modules/jest-mock/build/index.js:860
    offline

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        11.259s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58603653


我按照你的方法操作,但是当我创建测试时出现了一个错误:TypeError: Cannot set property 'innerHTML' of null Jest。在我的情况下,我有4行代码来操作DOM(在HTML中打印消息)。 - ArCiGo
我复制了你的代码,但 jest.spyOn() 没有改变 navigator.onLine 的值。不确定问题出在哪里。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接