首页 > 解决方案 > 使用“doMock”以避免提升时开玩笑不模拟模块

问题描述

我正在尝试模拟一个创建并返回另一个类的类。我有这个:

const mockMethod = jest.fn();

const mockClassA = jest.fn<ClassA>(() => ({
  method: mockMethod
}));

jest.mock("../src/ClassB", () => ({
  ClassB: {
    getClassA: () => new mockClassA()
  }
}));

由于提升,它被抓住了,mockClassA当 jest 嘲笑“../src/ClassB”时它是未定义的。

如果您不想提升,我已经阅读过,只需使用doMock

使用 babel-jest 时,对 mock 的调用将自动提升到代码块的顶部。如果您想明确避免此行为,请使用此方法。

https://jestjs.io/docs/en/next/jest-object#jestdomockmodulename-factory-options

当我运行时mock,我得到了TypeError: mockClassA is not a constructor,因为 mockClassA 是未定义的,因为它mock被提升到 mockClassA 的定义之上。

当我更改mock为 时doMock,它根本不会模拟模块 - 它使用真实的东西。


编辑:将它们声明为内联意味着我无法轻松访问模拟方法进行检查:

jest.mock("../src/ClassB", () => ({
  ClassB: {
    getClassA: () => ({
      method: jest.fn()
    })
  }
}));

因为getClassA是一个函数,所以它返回一个单独的对象实例method


编辑2:啊!设法像这样内联它:

jest.mock("../src/ClassB", () => {
  const mockMethod: jest.fn();
  return {
    ClassB: {
      getClassA: () => ({
        method: mockMethod
      })
    }
  };
});

标签: javascriptunit-testingjestjs

解决方案


我认为您在这里有两个选择:

  1. 使用jest.mock,内联mockClassAmockMethod,在模拟中公开它们,然后从'../src/ClassB'导入
  2. require使用 doMock,但在测试用例中使用动态。

推荐阅读