【问题标题】:Mock request module function using jest in typescript在打字稿中使用 jest 模拟请求模块功能
【发布时间】:2019-09-24 01:58:26
【问题描述】:

我正在尝试在打字稿中使用jest 模拟节点模块requestrequest() 函数,但我无法做到这一点,有人可以帮我哪里出错了吗?顺便说一句,我正在尝试创建一个通用代理函数,该函数应该适用于所有 http 方法,例如 get、post、delete、update。所以我只想使用request()函数,而不是request.get(),request.post()...等,使用基于请求方法的if-else阶梯。

代理.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);
  }
}

Proxy.spec.ts:

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

当我在上面运行测试时,我收到了错误: TypeError: request is not a function

【问题讨论】:

    标签: node.js typescript jestjs


    【解决方案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 会加载并运行您的测试文件并且已经将自己插入到全局范围内)

    【讨论】:

      猜你喜欢
      • 2019-08-28
      • 2019-07-16
      • 1970-01-01
      • 2018-02-24
      • 2018-01-18
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 2017-12-10
      相关资源
      最近更新 更多