typescript - 在每个 Jest 测试中模拟不同的 TypeScript 常量

标签 typescript unit-testing jestjs mocking ts-jest

我正在努力在每次测试的基础上用 Jest 模拟一个常量。我让它与下面的代码一起工作,但模拟是“静态的” - 我无法为每个测试进行不同的模拟。

代码:

// allowList.ts
export const ALLOW_LIST = {
  '1234': true
};
// listUtil.ts
import { ALLOW_LIST } from './allowList.ts';

export const checkList = (id: string) => {
  if (ALLOW_LIST[id]) return true;
  return false;
};

测试(工作):

// listUtil.test.ts
import { checkList } from './listUtil';

jest.mock('./listUtil', () => {
  return {
    '5678': true
  };
});

test('in list', () => {
  expect(checkList('5678')).toBe(true);
});
test('not in list', () => {
  expect(checkList('1234')).toBe(false);
});

我想要什么(不起作用):

// listUtil.test.ts
import { checkList } from './listUtil';

test('in list', () => {
  jest.mock('./listUtil', () => {
    return {
      '5678': true
    };
  });
  expect(checkList('5678')).toBe(true);
});
test('not in list', () => {
  jest.mock('./listUtil', () => {
    return {
      '9123': true
    };
  });
  expect(checkList('1234')).toBe(false);
});

我想做的事情可能吗? This post非常相似,并且在模拟函数时似乎可以工作,但我与已接受答案的评论者有同样的问题。我想我只是不明白 Jest 如何在幕后进行 mock 。我相信工作版本可以工作,因为模拟被提升并且基本上覆盖了真正的实现,但我不确定如何或是否可以在每个测试中实现这一点。

我认为一种选择是通过函数公开 ALLOW_LIST:

// allowList.ts
const ALLOW_LIST = {
  '1234': true
};
export const getAllowList = () => ALLOW_LIST;

并 mock 这一点,但我想知道这是否有必要。

最佳答案

您可以使用jest.doMock(moduleName, factory, options)为每个测试不同地模拟模块。

例如

allowList.ts:

export const ALLOW_LIST = {
  '1234': true,
};

listUtil.ts:

import { ALLOW_LIST } from './allowList';
console.log('ALLOW_LIST: ', ALLOW_LIST);

export const checkList = (id: string) => {
  if (ALLOW_LIST[id]) return true;
  return false;
};

listUtil.test.ts:

describe('65712158', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('should in list', () => {
    jest.doMock('./allowList', () => ({ ALLOW_LIST: { 5678: true } }));
    const { checkList } = require('./listUtil');
    expect(checkList('5678')).toBeTruthy();
  });

  it('should not in list', () => {
    jest.doMock('./allowList', () => ({ ALLOW_LIST: { 9123: true } }));
    const { checkList } = require('./listUtil');
    expect(checkList('1234')).toBeFalsy();
  });
});

单元测试结果:

 PASS  examples/65712158/listUtil.test.ts
  65712158
    ✓ should in list (2517 ms)
    ✓ should not in list (2 ms)

  console.log
    ALLOW_LIST:  { '5678': true }

      at Object.<anonymous> (examples/65712158/listUtil.ts:2:9)

  console.log
    ALLOW_LIST:  { '9123': true }

      at Object.<anonymous> (examples/65712158/listUtil.ts:2:9)

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

关于typescript - 在每个 Jest 测试中模拟不同的 TypeScript 常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65712158/

相关文章:

javascript - 附加到 Typescript 中的对象变量

interface - Typescript-使用类作为接口(interface),为什么我必须实现私有(private)成员/方法?

typescript - 了解 TypeScript 导入、模块和命名空间

c# - 绑定(bind)到 Excel 应用程序事件时 MissingMethodException

c# - 像在 WebOperationContext 中一样在模拟 WebOperationContext 中执行 CreateTextResponse(...)

reactjs - 使用 Jest 时是否有另一种方法来模拟组件的 mapDispatchToProps

javascript - 在react-native中测试按钮onClick功能

angular - typescript TS2532 : Object is possibly 'undefined' in two-way binding angular

java - Testng && Spring上下文单元测试 -> 在测试方法之前和之后执行sql

node.js - 无法从 PATH 中找到模块 'babel-preset-env' 您是说 "@babel/env"吗?