API with NestJS #167. Unit tests with the Drizzle ORM

NestJS

This entry is part 167 of 179 in the API with NestJS

Unit tests play a significant role in ensuring the reliability of our NestJS application. In this article, we’ll explain the concept behind unit testing and learn how to apply it to a NestJS application with the Drizzle ORM.

Introduction to unit tests

Unit tests allow us to verify that individual parts of our codebase function as expected on their own.

NestJS is configured to handle tests using the Jest framework out of the box. When we run the command, Jest finds files that follow a specific naming pattern. By default, NestJS is set up to look for files that end with . Alternatively, we can configure it to handle files that end with . To do that, we need to adjust the file.

Thanks to the above regular expression, Jest will pick up files that end with eiter or .

Writing our first unit test

Let’s take a look at the function in our .

authentication.service.ts

Let’s write a test ensuring our method returns a valid string.

authentication.service.test.ts

PASS src/authentication/authentication.service.test.ts
The AuthenticationService
when calling the getCookieForLogOut method
✓ should return a correct string

In our approach above, we call the constructor manually. Alternatively, we can use the NestJS test utilities to handle that instead. To achieve that, we need the method from the .

authentication.service.test.ts

With this alternative solution, we create a mock of the NestJS runtime. By calling the method, we set up a module with its dependencies similar to how the function in our file works.

Avoiding a real database

It’s crucial to notice that our connects to a real PostgreSQL database. If our database has any issues, our tests could fail. We don’t want that because unit tests should be independent and reliable.

One way of solving this problem is to recognize that it’s the class that uses the database under the hood. If we use a mocked version of the , we no longer need to connect to the database.

authentication.service.test.ts

Adjusting the mock for each test

In our test above, we mock the method in the to return a valid user each time. However, a particular method can yield various results in different situations. For example, the method:

  • if we provide a valid email of a user who’s signed up, it returns the user,
  • when a user with the provided email does not exist, it throws the .

Let’s create a mock that can cover both cases. To do that, let’s create the variable and use it in the mocked .

Then, let’s use function when we want the method to return a value successfully. When we want it to fail, we have to use .

authentication.service.test.ts

PASS src/authentication/authentication.service.test.ts
The AuthenticationService
when calling the getCookieForLogOut method
✓ should return a correct string
when registering a new user
and when the usersService returns the new user
✓ should return the new user
when the getAuthenticatedUser method is called
and a valid email and password are provided
✓ should return the new user
and an invalid email is provided
✓ should throw the BadRequestException

Focusing on a single class or function is an essential aspect of unit testing. Therefore, we must focus on testing the methods of the and ensure our tests don’t rely on the code of the . We must make sure the classes work as expected in isolation instead of checking how they work together.

Mocking the Drizzle ORM

We haven’t yet tested a class that uses the Drizzle ORM directly. Let’s take a look at the method in our .

users.service.ts

There are two major cases in our method:

  1. if the method returns the user, the should return it too,
  2. if the method returns undefined, should throw the .

To test both situations, we need to mock the .

users.service.test.ts

Thanks to adjusting the mock for each case using , we can cover both cases.

PASS src/users/users.service.test.ts
The UsersService
when the getById function is called
and the findFirst method returns the user
✓ should return the user
and the findFirst method does not return the user
✓ should throw the NotFoundException

Summary

In this article, we’ve covered the basics of unit testing and how to apply it in a NestJS application. To practice, we’ve used services that use Drizzle ORM under the hood to connect to the database. Since unit tests should not rely on a real database connection, we learned how to mock services, including the Drizzle Service. While this provides a solid foundation for testing a NestJS application with Drizzle ORM, there is still more to learn. Stay tuned!

Series Navigation<< API with NestJS #166. Logging with the Drizzle ORMAPI with NestJS #168. Integration tests with the Drizzle ORM >>
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments