使用TypeScript使用Jest测试或模拟未导出的函数

时间:2019-02-14 18:39:34

标签: typescript unit-testing jestjs

是否可以使用TypeScript使用Jest测试未导出的函数?我已经看到推荐一些rewire之类的库的答案,但是看来它们还不真正兼容TypeScript。另一种方法是也导出这些 private 函数,但是我认为必须有一个解决方案,而不必仅出于测试目的而导出。

设置如下。有两种功能,一种是导出的,一种不是。

export function publicFunction() {
  privateFunction();
}

function privateFunction() {
  // Whatever it does
}

在我的单元测试中,我想解决两种情况。测试privateFunction本身,并对其进行publicFunction测试的模拟。

我在测试时使用 ts-jest 来编译打字稿文件。 jest.config.json 看起来像

{
  "transform": {
    "^.+\\.(t|j)sx?$": "ts-jest"
  },
  "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(tsx?)$",
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
  "testEnvironment": "node",
  "globals": {
    "ts-jest": {
      "tsConfig": "test/tsconfig.spec.json"
    }
  }
}

我对jest.fn()很熟悉,但是我不知道如何覆盖或提取私有函数。单元测试就像

import { publicFunction } from '../src';

describe('publicFunction', () => {
  it('should call "privateFunction" once', () => {
    // Overwrite privateFunction with jest.fn();

    publicFunction();

    expect(...).toHaveBeenCalled(1);
  });
});

或者测试无法导入的私有功能。

import { privateFunction } from '../src/index'

describe('privateFunction', () => {
  it(...
});

有什么想法或建议吗?谢谢!

1 个答案:

答案 0 :(得分:5)

为了使用JEST和Typescript测试未导出的功能,我使用了Rewire。几乎没有问题,我们必须提供重新连接TS构建文件夹的路径,而不是.ts文件路径。

以下是我的目录结构:

app
|---dist
    |---controllers
        |---api.js
    src
    |---controllers
        |---api.ts
        |---api.spec.ts

因此对于重新布线,我必须提供./dist/controllers/api而不是./src/controllers/api的路径

这是我的示例代码:

import rewire from "rewire";

const api = rewire('../../dist/controllers/api');   // path to TS build folder

describe("API Controller", () => {
    describe('Fetch Route Params', () => {

        let fetchRouteParams: (url: string) => string;

        beforeEach(() => {
            fetchRouteParams = api.__get__('fetchRouteParams'); // non-exported function
        });

        it('should fetch route params from url', () => {
            const url = "https://example.com/foo/api/products";
            expect(fetchRouteParams(url)).toEqual('foo/api/products');
        });

        it('should not fetch route params from url', () => {
            const url = "";
            expect(fetchRouteParams(url)).toEqual('');
        });
    });
});

除了使用rewire外,我什至没有遇到更好的解决方案。但是它可以用于测试未导出的功能。

我使用过的NPM软件包:

npm i -D rewire
npm i -D @types/rewire

希望有帮助,谢谢。