【问题标题】:Unable to use jest.mock for TypeScript class无法将 jest.mock 用于 TypeScript 类
【发布时间】:2019-08-01 14:30:18
【问题描述】:

我尝试按照 Jest 文档中的 ES6 Class Mocks 页面来测试 TypeScript 类 Consumer 上的方法。该类实例化了一个Provider 对象并在其上调用方法,所以我想模拟Provider 类。

目录结构:

.
├── __tests__
│   └── consumers
│       └── Consumer.test.ts
└── js
    ├── providers
    │   └── provider.ts
    └── consumers
        └── Consumer.ts

provider.ts:

export class Provider {
    constructor() {}

    public action(params) {
        // do some stuff that we need to mock
        return something;
    }
}

Consumer.ts:

import {Provider} from "../providers/provider";

export class Consumer {
    private provider: Provider;

    constructor() {
        this.provider = new Provider();
    }

    public doSomething() {
        const result = this.provider.action(params);
        // do something with 'result'
    }
}

我的第一次尝试是使用默认的“自动模拟”:

Consumer.test.ts:

import {Consumer} from "../../js/consumers/Consumer";

jest.mock("../../js/providers/provider");

test("Consumer doSomething", () => {
    // a mock Provider will be instantiated in Consumer's ctor:
    const consumer = new Consumer();

    // however, Provider.action() will return undefined within doSomething()
    consumer.doSomething();
});

这证明我可以用mock代替真正的实现,但是我需要保证Provider.action()返回一个值,所以接下来我尝试了:

// at some point we can make this return something, but first check it works
const mockAction = jest.fn();
jest.mock("../../js/providers/provider", () => {
  return jest.fn().mockImplementation(() => {
    return {action: mockAction};
  });
});

test("Consumer doSomething", () => {
    // throws TypeError: provider_1.Provider is not a constructor
    const consumer = new Consumer();

    consumer.doSomething();
});

无论我如何尝试更改模拟,我都找不到允许我在测试中正常使用Consumer 的解决方案。我宁愿避免创建“手动模拟”,这样我可以保持代码库更清洁并在测试之间改变模拟实现。

【问题讨论】:

    标签: javascript typescript unit-testing jestjs


    【解决方案1】:

    您不必在此处使用默认导出。使用命名导出时,您需要创建一个与模块的“形状”相匹配的模拟。所以在你的情况下:

    const mockAction = jest.fn();
    jest.mock("../../js/providers/provider", () => ({
     Provider: jest.fn().mockImplementation(() => ({
        action: mockAction
      }))
    ));
    

    【讨论】:

      【解决方案2】:

      我似乎已经通过确保要模拟的依赖项是默认导出来解决这个问题:

      Provider.ts:

      export default class Provider {}
      

      Consumer.tsConsumer.test.ts

      import Provider from "../providers/provider";
      

      我相信这是因为jest.mock()模块为目标,而provider 是一个具有Provider 类的模块在其中定义。如果该模块中没有默认导出,则模拟的确切目标是模棱两可的。通过将类设为默认导出,Jest 知道将其用作模拟的目标。

      【讨论】:

        猜你喜欢
        • 2022-06-18
        • 2021-06-15
        • 2019-06-16
        • 1970-01-01
        • 2023-01-26
        • 1970-01-01
        • 2018-10-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多