简体   繁体   English

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

[英]How can you mock imported functions in TypeScript using Jest?

I am having a module called map-creation.service.ts : 我有一个名为map-creation.service.ts的模块:

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

};

Which is used in my endpoint: 在我的端点中使用哪个:

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'});
});

When I am trying to mock this module in my tests, and want to test if it was called when requesting the endpoint, I still get: Expected mock function to have been called with: ... But it was not called. 当我试图在我的测试中模拟这个模块,并且想要测试它是否在请求端点时被调用时,我仍然得到: 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';

And here's my test: 这是我的测试:

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

If I am mocking the method like this: 如果我嘲笑这样的方法:

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

The test passes, but tslint is complaining: Cannot assign to 'createMap' because it is not a variable . 测试通过,但tslint抱怨: Cannot assign to 'createMap' because it is not a variable So what would be the proper way to mock this method in TypeScript and Jest? 那么在TypeScript和Jest中模拟这个方法的正确方法是什么?

So what would be the proper way to mock this method in TypeScript and Jest? 那么在TypeScript和Jest中模拟这个方法的正确方法是什么?

Use dependency injection to inject the mock vs. real version of functions as needed. 使用依赖注入根据需要注入模拟与实际版本的函数。

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

but tslint is complaining: Cannot assign to 'createMap' because it is not a variable 但tslint抱怨:无法分配给'createMap',因为它不是变量

Please don't do this. 请不要这样做。 Imports should be considered immutable. 进口应被视为不可变的。 You will get a compile time TypeScript error for this as well and when module support becomes native you will get a runtime error. 您将获得编译时TypeScript错误,当模块支持变为本机时,您将收到运行时错误。

The issue with dependency injection is that it requires you to restructure all of your existing solution in order for your code to behave appropriately under test. 依赖注入的问题是它需要您重构所有现有解决方案,以便您的代码在测试中表现得恰当。 It also ignores the fact that ES6 already has an import/export system that can be hijacked. 它也忽略了ES6已经有一个可以被劫持的导入/导出系统的事实。

ts-mock-imports is a library that is designed to handle mocking imports without dependency injection. ts-mock-imports是一个用于处理模拟导入但没有依赖注入的库。

In your test file: 在您的测试文件中:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM