无法将jest.mock用于TypeScript类

时间:2019-03-11 09:47:49

标签: javascript typescript unit-testing jestjs

我试图按照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();
});

这证明我可以用模拟代替真正的实现,但是我需要确保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。我宁愿避免创建“手动模拟”,这样可以使代码库更整洁并在测试之间改变模拟实现。

1 个答案:

答案 0 :(得分:0)

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

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