使用请求对 NestJS 控制器进行单元测试

Posted

技术标签:

【中文标题】使用请求对 NestJS 控制器进行单元测试【英文标题】:Unit testing NestJS controller with request 【发布时间】:2018-12-27 13:37:07 【问题描述】:

我的 Controller 函数定义如下所示: async login(@Req() request, @Body() loginDto: LoginDto): Promise<any>

如何准备/模拟请求以提供来自 Jest 测试的函数的第一个参数? 在函数内部,我使用request.res.set 设置标题。我应该以某种方式将真实的 Request 对象传递给函数,然后检查是否设置了标头,还是模拟整个 Request 对象并检查是否调用了 set 函数?

【问题讨论】:

【参考方案1】:

我设法使用 node-mocks-http 库来模拟请求和响应。

const req = mocks.createRequest() req.res = mocks.createResponse()

然后将其作为参数传递。

const data = await authController.login(req, loginDto) expect(req.res.get('AccessToken')).toBe(token.accessToken)

【讨论】:

在 NestJS 中这是一种好的(惯用的)方法吗,因为它应该负责通过注入解决所有依赖项?我只是问,因为我也在寻找一种方法来实现它。 这不再有效,类型已更改并且 createRequest() 的返回类型与控制器需要的不兼容。 现在该怎么做?【参考方案2】:

我采用了不同的方法,我没有使用node-mocks-http库,而是使用@golevelup/ts-jest,也没有测试函数是否返回一些值,比如res.json()res.status(),我检查了函数是否被调用具有我想要的价值。

我从好老Kent C. Dodds's testing workshop那里借用了这种方法,看看类似的想法。无论如何,这就是我为了mock 我的Controller's routeResponse 依赖所做的:

  // cars.controller.spec.ts
  import  createMock  from '@golevelup/ts-jest';

  const mockResponseObject = () => 
    return createMock<Response>(
      json: jest.fn().mockReturnThis(),
      status: jest.fn().mockReturnThis(),
    );
  ;


  ... ommited for brevity

  it('should return an array of Cars', async () => 
    const response = mockResponseObject();

    jest
      .spyOn(carsService, 'findAll')
      .mockImplementation(jest.fn().mockResolvedValueOnce(mockedCarsList));

    await carsController.getCars(response);

    expect(response.json).toHaveBeenCalledTimes(1);
    expect(response.json).toHaveBeenCalledWith( cars: mockedCarsList );
    expect(response.status).toHaveBeenCalledTimes(1);
    expect(response.status).toHaveBeenCalledWith(200);
  );

就是这样,我认为实现细节并不那么重要,但无论如何我会将链接留给Github repo,在那里你可以找到整个项目。

【讨论】:

@golevelup/ts-jest 是为此类问题创建的 供参考:@golevelup/ts-jest

以上是关于使用请求对 NestJS 控制器进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

如何对 NestJS 中的控制器应用警卫进行单元测试?

使用 NestJS 服务单元测试未找到连接“默认”

NestJS如何在单元测试中创建新的猫鼬模型?

在 NestJS 中使用 Jest 和 MongoDB 进行单元测试

服务的 NestJS 单元测试:模拟 getManager 导致“未找到连接“默认””错误

对指令进行单元测试 - 无法强制使用虚假数据