开玩笑-快速测试

时间:2020-09-08 23:51:26

标签: express jestjs nestjs

我有一个用于简单的汽车买卖API的控制器,

async processCarSale(@Res() res: any) {
    if(carSaleService.sale()) {
        return res.status(201).send(<some-body>);
    }
    return res.status(204).send(<some-other-body>);
}

我正在尝试通过单元测试来测试状态代码是否设置正确。谷歌搜索和使用SO我发现了与此类似的示例

const mockResponse = {
    status: jest.fn(),
    send: jest.fn()
}
const mockResponseSent = { send: jest.fn() };
mockResponse.status = jest.fn(() => mockResponseSent);

await carController.processCarSale(response);
expect(response.statusCode).toBe(200);

但是,这似乎并没有实际测试状态码。

是否可以测试通过Express在响应中发送的statusCode?

2 个答案:

答案 0 :(得分:1)

您可以使用supertestprovided by default with Nestjs)来实现。

您可以使用还提供的HttpStatus枚举,该枚举提供所有HTTP代码状态。

test('/route (POST)', () => {
  const data = { any: 'data', what: 'you want' }
  request(app.getHttpServer())
            .post('/route')
            .send(data)
            .expect(HttpStatus.CREATED)
            .expect('Content-Type', /json/)
}

答案 1 :(得分:0)

您的模拟程序从未设置过名为statusCode的值,它只是对功能进行了存根并返回相同的对象,因此也可以调用send()(也是存根)。如果您想测试res.statusCode === 200之类的内容,则可以执行以下操作:

const mockResponse = {
    status: jest.fn(),
    send: jest.fn(),
    statusCode: 0
}
const mockResponseSent = { send: jest.fn() };
mockResponse.status = jest.fn(() => {
  mockResponseSent.statusCode = 200;
  return mockResponseSent;
});

await carController.processCarSale(response);
expect(response.statusCode).toBe(200);

但是,这本质上是jsut首先重新编写控制器的逻辑,但这并不是很好。因此,最好在可行的地方采用Jest的mockImplementation()方法

const mockResponse = {
    status: jest.fn(),
    send: jest.fn()
}
const mockResponseSent = { send: jest.fn() };
mockResponse.status = jest.fn().mockImplementation((status) => {
  mockResponseSent.statusCode = status;
  return mockResponseSent;
});

await carController.processCarSale(response);
expect(response.statusCode).toBe(200);

总的来说,我建议您在控制器中放弃使用res,并建议让Nest处理http状态代码的设置并发送响应。您可以使用@HttpCode()

将代码设置为默认值以外的其他值