我正在尝试在打字稿中使用request()
来模拟节点模块request
的{{1}}函数,但是我无法做到这一点,有人可以帮助我哪里出了问题吗?顺便说一句,我试图创建一个通用代理函数,该函数应与所有http方法(例如get,post,delete,update)一起使用。所以我只想使用jest
函数,而不是使用基于请求方法的if-else梯形图来代替request.get(),request.post()... etc。
Proxy.ts:
request()
Proxy.spec.ts:
import * as request from 'request';
export default class ProxyClass {
static proxy(req: any, res: any): any {
const options: any = {
headers: req.headers,
}
const proxyReq: any = request(options);
proxyReq.on('error', (err: any) => {
return res.status(500).send(err);
});
return proxyReq.pipe(res);
}
}
当我通过测试时,我得到了错误:
import 'jest';
import * as request from 'request';
import {Request} from 'jest-express/lib/request';
import {Response} from 'jest-express/lib/response';
import ProxyClass from './Proxy';
describe('proxy request', () => {
const req: any = new Request();
const res: any = new Response();
it('should call pipe', () => {
const mockRequest = {
pipe: jest.fn(),
on: jest.fn(),
}
jest.mock('request', () => {
return function() {
return mockRequest;
}
});
ProxyClass.proxy(req, res);
expect(mockRequest.pipe).toHaveBeenCalledTimes(1);
jest.clearAllMocks();
});
});
答案 0 :(得分:1)
如果您获得TypeError: request is not a function
,则可能是在TypeScript配置中将esModuleInterop
设置为true
。
在这种情况下,您需要像这样导入request
:
import request from 'request';
TypeScript和ES6模块与旧模块样式不同,esModuleInterop
标志告诉TypeScript做一些额外的工作来编译旧模块的import
语句,使其像新样式一样工作。 ..在这种情况下,将单个函数导出视为TypeScript / ES6模块的default
导出。
jest.mock
doesn't work inside a test,因此您需要将其移至测试之外。
如果您将工厂函数作为第二个参数传递,则它必须是完全独立的,因为对jest.mock
的调用会被吊起,并且将在测试文件中的其他任何函数之前运行。
在这种情况下,您可以使模拟对象每次都返回相同的对象,这样您就可以在测试期间获取模拟对象并检查其是否按预期被调用:
import request from 'request';
import {Request} from 'jest-express/lib/request';
import {Response} from 'jest-express/lib/response';
import ProxyClass from './Proxy';
jest.mock('request', () => {
const mockRequest = {
pipe: jest.fn(),
on: jest.fn(),
}
return function() {
return mockRequest; // <= returns the same object every time...
}
});
describe('proxy request', () => {
const req: any = new Request();
const res: any = new Response();
it('should call pipe', () => {
const mockRequest = request(); // <= ...so you can get it here
ProxyClass.proxy(req, res);
expect(mockRequest.pipe).toHaveBeenCalledTimes(1); // Success!
jest.clearAllMocks();
});
});
(请注意,您不需要导入jest
,因为jest
会加载并运行您的测试文件,并且已经将其自身插入了全局范围)