Unit Tests for Node.js APIs built with TS, Express.js and TypeORM
Some days ago I wrote a story about how I structure my Node.js REST APIs. However, I didn’t cover any test scenarios in there. So it’s time to catch up on this now.
We’re going to write an unit test for a single API component based on the project structure from my other story. The goal is to test the component by mocking a database and sending an HTTP request to its routes.
For writing tests I use the following node modules:
- Mocha
- Chai
- Supertest
Project structure
This is the project structure I mentioned above. Of course, you can use any other as well.
nodejs-api-structure
└───src
│
└───config
│
└───api
│ │
│ └───components
│ │ │
│ │ └───user
│ │ │ controller.ts
│ │ │ model.ts
│ │ │ routes.ts
│ │ │ service.ts
│ │ │ user.spec.ts
│ │
│ └───middleware
│ │
│ │ routes.ts
│ │ server.ts
│
└───test
│ │ factory.ts
│
│ index.ts
We’ll focus on the following files:
- factory.ts
- user.spec.ts
Test Factory - factory.ts
This file is some kind of a setup file for each single unit test. It takes care of the database connection and starts the Express.js server.
We use ‘sqljs’ as database type, so it’s not necessary to provide a real database like MySQL or any other.
Actually, the code should be self explanatory. The class acts like a container for the database connection and express server. It provides getter methods to make them accessible and a method to open / close the connections.
Component test - user.spec.ts
This file covers the unit test for the API component. In there, we use different HTTP request methods like POST, PUT, GET and DELETE to test the component’s API endpoints.
First of all, we create a new instance of the TestFactory
class and User
model. The mockTestUser
methods returns an instance of User
including some dummy data. Moreover we create another instance testUserModified
with some modified properties which will be used to test the PUT endpoints.
Now we define Mocha’s before
and after
methods. before
is executed before the test starts and after
is executed after the test has ended.
Inside them we call the factory’s init
and close
method which establish a new database connection and express server before the test starts and disconnects from it when he has ended.
One important thing to notice is when you have multiple unit tests, that each test establishes a new database connection and express server.
For making HTTP requests to the server I use Supertest and Chai for validating the server responses.
Here’s the complete code for one component:
This article was originally published on my blog. Have a look.
I’m currently working on a side project, where you can see test scenarios like this one in action. Have a look at the User
or Task
model for example in there.