API with NestJS #9. Testing services and controllers with integration tests

Express JavaScript NestJS Testing TypeScript

This entry is part 9 of 10 in the API with NestJS

In the previous part of this series, we’ve focused on unit tests. This time, we look into integration tests. In this article, we explain their principles and how they differ from unit tests. We write a few of them using Jest to test our services. We also look into the SuperTest library to test our controllers.

Testing NestJS services with integration tests

When our unit tests pass, it indicates that parts of our system work well on their own. However, an application consists of many parts that should work well together. A job of an integration test is to verify that all the cogs in the wheel integrate. We can write such tests integrating two or more parts of the system.

Let’s test how  integrates with .


The first thing to notice above is that we mock some of the services that we use. Even though we want to write an integration test, it does not mean that we need to include every part of the system.

Mocking some parts of the system

We need to decide how many parts of the system we want to include. Let’s assume that we want to test the integration of the   and  . Going further, let’s also mock the bcrypt library.

Since our   directly imports it, it is not straightforward to mock. To do that, we need to use  .

Now that we explicitly state that we mock bcrypt, we can provide our implementation of it.

Thanks to declaring   at the top, we can now change its implementation for each test.

We do a similar thing for the repository.

Providing different implementations per test

Once we do all of the above, we can provide different implementations of our mocked services for various tests.

Above, we specify how our mocks work in the   functions. Thanks to doing that, it would run before all the tests in a particular  block.

Check out this file in the repository, if you want to inspect the above test suite thoroughly.

Testing controllers

We perform another type of integration tests by performing real requests. By doing so, we can test our controllers. It is closer to how our application is used. To do so, we use the SuperTest library.

Now, let’s test how the  integrates with   and  .

We start by mocking some of the parts of the application.

Please notice that above we also need to apply the   if we want to verify our validation.

Once we have our module ready, we can perform some tests on it. Let’s start with the registration flow.

Above, we perform real HTTP requests and test the   endpoint. If we provide valid data, we expect it to work correctly. Otherwise, we expect it to throw an error.

Aside from simple tests like those above, we can perform more throughout ones. For example, we can verify the response headers. For a full list of SuperTest features, check out the documentation.

To see the whole controller test suite, check it out in the repository.


In this article, we’ve gone through ways to write integration tests for our NestJS API. Aside from testing how our services integrate, we’ve also used the SuperTest library and tested a controller. By writing integration tests, we can thoroughly verify if our app works as expected. Therefore, it is a topic worth diving into.

Series Navigation<< API with NestJS #8. Writing unit testsAPI with NestJS #10. Uploading public files to Amazon S3 >>
Notify of