如何使用Jest在TypeScript中模拟导入的函数?

时间:2017-04-18 13:11:42

标签: typescript unit-testing mocking jestjs

我有一个名为map-creation.service.ts的模块:

export const createMap = (asyncJobId: string, resourceUrl: string, s3DestFolder: string) => {

};

我的终端使用了哪个:

import {createMap} from './services/map-creation.service';

const router = express.Router();
const routePrefix = config.get('server.routePrefix');

router.post(`/${routePrefix}`, validate(validation), (req: express.Request, res: express.Response) => {
    createMap(req.body.asyncJobId, req.body.resourceUrl, req.body.s3DestFolder);
    res.status(201).json({message: 'Created'});
});

当我试图在我的测试中模拟这个模块,并且想要测试它是否在请求端点时被调用时,我仍然得到:Expected mock function to have been called with: ... But it was not called.

jest.mock('../../../src/services/map-creation.service');
import {createMap} from '../../../src/services/map-creation.service';

这是我的测试:

it('should call the map-creation service', () => {
        return request(server)
            .post(`/${routePrefix}`)
            .send({
                asyncJobId,
                resourceUrl,
                s3DestFolder
            })
            .then(res => {
                expect(createMap).toBeCalledWith(asyncJobId, resourceUrl, s3DestFolder);
            });
    });

如果我嘲笑这样的方法:

import {createMap} from '../../../src/services/map-creation.service';
createMap = jest.fn();

测试通过,但tslint抱怨:Cannot assign to 'createMap' because it is not a variable。那么在TypeScript和Jest中模拟这个方法的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

  

那么在TypeScript和Jest中模拟这个方法的正确方法是什么?

使用依赖注入根据需要注入模拟与实际版本的函数。

DI的推荐框架:http://inversify.io/

  

但tslint抱怨:无法分配到' createMap'因为它不是变量

请不要这样做。进口应被视为不可变的。您将收到编译时TypeScript错误,当模块支持变为本机时,您将收到运行时错误。

答案 1 :(得分:0)

依赖注入的问题在于,它要求您重组所有现有解决方案,以使代码在测试中能够正常运行。它还忽略了ES6已经具有可以劫持的导入/导出系统的事实。

ts-mock-imports是一个旨在处理模拟导入而无需依赖项注入的库。

在您的测试文件中:

import * as createMapModule from '../../../src/services/map-creation.service';
import { ImportMock } from 'ts-mock-imports';

const mockHandler = ImportMock.mockOther(createMapModule, 'createMap', jest.fn());

<-- Test Code Here --->

// Ensure you restore the mock once the tests are complete
mockHandler.restore()