Hey !
I don't know how to test Nest api routes with supertest.
Someone already try this ?
Hi @ThomRick,
The same way as with express. It is possible to pass custom express
instance as a second argument of NestFactory.create
method.
import * as request from 'supertest';
import * as express from 'express';
import { NestFactory } from '@nestjs/core';
const instance = express();
@Controller()
class UsersController {
@Get('user')
getUser(req, res) {
res.status(200).json([]);
}
}
@Module({
modules: [],
controllers: [UsersController],
})
export class ApplicationModule {}
const app = NestFactory.create(ApplicationModule, instance);
app.listen(3000, () => console.log('Application is listening on port 3000.'));
///////////// Test
request(instance)
.get('/user')
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
Hey @kamilmysliwiec,
The thing is I don't know why you have to call the listen() function ?
I wrote this test file that work fine:
import {NestFactory} from '@nestjs/core';
import {RegistrationModule} from './registration.module';
import * as request from 'supertest';
import {expect} from 'chai';
import {ExpressAdapter} from '@nestjs/core/adapters/express-adapter';
import {Application} from 'express';
import {INestApplication} from '@nestjs/common/interfaces/nest-application.interface';
describe('RegistrationModule', () => {
let instance: Application;
before(() => {
instance = ExpressAdapter.create();
const application: INestApplication = NestFactory.create(RegistrationModule, instance);
application.listen(8080, () => console.log('Application listening at port 8080'));
});
it('should expose GET /api/registrations endpoint', done => {
request(instance)
.get('/api/registrations')
.end((error, response) => {
expect(response.status).to.not.be.equal(404);
done();
});
});
it('should expose POST /api/registrations endpoint', done => {
request(instance)
.post('/api/registrations')
.end((error, response) => {
expect(response.status).to.not.be.equal(404);
done();
});
})
});
But I couldn't write the test init like this:
beforeEach(() => {
instance = ExpressAdapter.create();
const application: INestApplication = NestFactory.create(RegistrationModule, instance);
application.listen(8080, () => console.log('Application listening at port 8080'));
});
Because it throws this exception:
Uncaught Error: listen EADDRINUSE :::8080
at Object.exports._errnoException (util.js:1050:11)
at exports._exceptionWithHostPort (util.js:1073:20)
at Server.setupListenHandle [as _listen2] (net.js:1259:14)
at listenInCluster (net.js:1307:12)
at Server.listen (net.js:1406:7)
at Function.listen (node_modules/@nestjs/core/node_modules/express/lib/application.js:617:24)
at NestApplication.listen (node_modules/@nestjs/core/nest-application.js:26:29)
at exceptions_zone_1.ExceptionsZone.run (node_modules/@nestjs/core/nest-factory.js:47:35)
at Function.run (node_modules/@nestjs/core/errors/exceptions-zone.js:8:13)
at Proxy.args (node_modules/@nestjs/core/nest-factory.js:46:70)
at Context.beforeEach (src/application/modules/registration/registration.module.spec.ts:15:17)
So I though to close the server and I had looking for what return listen() function ==> nothing... not as express that it return the http.Server.
So impossible to close the server...
I didn't try yet to execute more than one test file but I smell a problem with the listen()...
Hi @ThomRick,
Update your packages into 2.1.0
version. Now listen()
method should returns http server. Futhermore, I added close()
methods in INestApplication
and INestMicroservice
.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Hi @ThomRick,
Update your packages into
2.1.0
version. Nowlisten()
method should returns http server. Futhermore, I addedclose()
methods inINestApplication
andINestMicroservice
.