I've struggling with this for a few hours. I'm coding a sample API with NestJS, and I'm adding some tests for an endpoint that receives latitude and longitude as query params and returns an array of restaurants located up to a certain distance. I added the necessary type validations for the query params, but I'm unable to trigger a bad request scenario in the tests. My test file looks something like this:
import { INestApplication } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import * as request from 'supertest';
import { RestaurantController } from './restaurant.controller';
import { RestaurantService } from './restaurant.service';
import { successResponse } from '../../test/mocks';
describe('RestaurantController', () => {
let app: INestApplication;
beforeAll(async () => {
const testApp: TestingModule = await Test.createTestingModule({
controllers: [RestaurantController],
providers: [RestaurantService],
}).compile();
app = testApp.createNestApplication();
await app.init();
});
describe('GET /restaurant/location', () => {
const url = '/restaurant/location';
it('should return a list of near restaurants', () => {
return request(app.getHttpServer())
.get(url)
.query({ latitude: -34.661369, longitude: -58.362257 })
.expect(200)
.expect(successResponse);
});
it('should throw an error because the latitude is invalid', () => {
return request(app.getHttpServer())
.get(url)
.query({ latitude: 'I am not a valid latitude', longitude: -58.362257 })
.expect(400);
});
});
});
The success scenario works as expected, but in the second case, when I'm expecting to receive a status 400, the request keeps resolving to 200. This is the error message I get on the terminal:
FAIL src/restaurant/restaurant.controller.spec.ts
● RestaurantController › GET /restaurant/location › should throw an error because the latitude is invalid
expected 400 "Bad Request", got 200 "OK"
44 | .get(`${url}?latitude=invalid&longitude=-58.362257`)
45 | .query({ latitude: 'I am not a valid latitude', longitude: -58.362257 })
> 46 | .expect(400);
| ^
47 | });
48 | });
49 | });
at Object.<anonymous> (src/restaurant/restaurant.controller.spec.ts:46:10)
----
at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
at node_modules/supertest/lib/test.js:306:17
at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
at Test.assert (node_modules/supertest/lib/test.js:164:23)
at Server.localAssert (node_modules/supertest/lib/test.js:120:14)
If I do the exact same request in the browser or postman, it fails as expected. What am I missing?
Thanks in advance.
So, the problem was pretty simple. I'm using ValidationPipe to validate the query params, and for some reason I assumed that it was being bound to the testApp out of the box. Thing is, it has to be done explicitly:
const testApp: TestingModule = await Test.createTestingModule({
controllers: [RestaurantController],
providers: [RestaurantService],
}).compile();
app = testApp.createNestApplication();
// This was the missing part
app.useGlobalPipes(
new ValidationPipe({ whitelist: true, transform: true }),
);
await app.init();