Daniel’s Substack

Daniel’s Substack

Share this post

Daniel’s Substack
Daniel’s Substack
How to Test Your Node.js RESTful API with Vitest: Unit & Integration Testing

How to Test Your Node.js RESTful API with Vitest: Unit & Integration Testing

Learn step-by-step how to add unit and integration tests to your Node.js and Express API using Vitest. Includes clear examples and GitHub repository.

Daniel Osorio's avatar
Daniel Osorio
Apr 17, 2025
∙ Paid

Share this post

Daniel’s Substack
Daniel’s Substack
How to Test Your Node.js RESTful API with Vitest: Unit & Integration Testing
1
Share
AI-generated image created by the Author

Introduction

In my previous article, we created a foundational Node.js RESTful API using Express.js, MongoDB, and TypeScript.

The API is for a to-do task manager and contains the basic operations you would expect: creating, retrieving, updating, and deleting a task.

You can check it here:

Build Your First RESTful API with Node.js, Express, MongoDB, and TypeScript

Build Your First RESTful API with Node.js, Express, MongoDB, and TypeScript

Daniel Osorio
·
Apr 11
Read full story

At the end of that article, I listed extra steps to enhance our API and make it more robust.

One critical first enhancement is adding automated tests to ensure the reliability and maintainability of our application.

In this article, we'll explore why tests matter, discuss different types of testing (unit and integration tests specifically), and demonstrate how to implement them using Vitest.

Prerequisites

I will assume the following:

  • You have a basic understanding of JavaScript/TypeScript.

  • You have Node.js and npm installed on your local machine.

  • To follow along, you downloaded the repository from https://github.com/daniosoriov/todo-manager.

Even if you’re newer to testing, I aim to keep explanations straightforward and accessible.


Why are Tests Important?

Tests can be a controversial topic in software development.

Some people hate them, some people love them.

Regardless of your feelings about testing, we must understand the benefits of a well-tested application and why it is essential.

Tests help us:

  • Catch bugs and errors early during development.

  • Ensure that our code behaves as expected under different conditions.

  • Increase maintainability.

  • Reduce the risk of introducing new issues.

  • Reduces costs associated with fixing bugs later on.

  • Enhance the quality of our application and, consequently, the user experience for those who use it.

  • Identify areas for improvement or optimization.

So, why do some people dislike them if they are so important?

The main reason is time consumption.

Teams with a tight schedule or budget may find testing to be an additional burden rather than a valuable investment, betting that their developers will not make costly mistakes down the road.

However, this is a dangerous assumption because even minor bugs can significantly affect your application's functionality.

Hence, it should always be a priority in any software development project to include thorough initial testing.


What are Automated Tests?

When developing an application and implementing tests, we typically encounter three distinct types of tests:

  • Unit tests.

  • Integration tests.

  • End-to-end (E2E) tests.

I will briefly go through each of them to give you a better idea of what they are and how we will use them in our application.

Unit Tests

As the name suggests, unit tests cover a specific “unit” of our application.

The unit can be a function, middleware, or any other piece of code that can be tested in isolation.

Unit tests help us guarantee that the smaller parts of our code are working correctly.

However, external interactions (like database queries or API calls) are typically mocked, meaning we simulate these external interactions without actually performing them.

The idea is to isolate the code you're testing.

Unit tests typically verify scenarios such as:

  • Correct behavior when valid data is provided.

  • Proper handling when mandatory data is missing or invalid.

For example, when creating a task, the unit test should:

  • Return a successful status code when all the fields required to create a task are provided.

  • Return an error status if, for example, the title field is empty.

  • Return an error status if the status is not among “pending”, “in-progress”, or “completed”.

  • And so on…

With these tests, we can scrutinize the Create Task behaviour and guarantee it is not doing something it shouldn’t be doing.

Integration Tests

Integration tests are a bit more complex than unit tests.

Integration tests verify that multiple components (routes, middleware, database connections, etc.) interact correctly.

Unlike unit tests, integration tests often interact with a real or test database to ensure realistic behavior.

If we continue with our create task example, our integration tests would cover the flow from the initial request, passing through all the middleware on our route, to the final method, creating the task.

For example, to check that a task is successfully created, our integration test should:

  • Pass through any validation middlewares without errors.

  • Get to the method that creates the task.

  • Create the task in the database.

  • Return the created task.

All of these steps should not fail, and they will demonstrate how the different components of our application interact during task creation.

Integration tests are also used to check scenarios of failure.

For example, the application should not create the task if we forget to pass one of its mandatory fields. And so on…

End-to-end (E2E) Tests

Although we won’t cover end-to-end tests in this article, I want to explain them briefly.

End-to-end (E2E) tests validate your application's workflow, simulating a real user's experience from the frontend interface through backend API interactions and database operations.

Since we do not have a client application in our example, I will skip end-to-end tests, but know that these are also highly important.

Before we continue, I want to discuss the primary tool we will use to create the tests for our application.


What is Vitest?

Vitest is a testing framework that excels in its speed.

Keep reading with a 7-day free trial

Subscribe to Daniel’s Substack to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Daniel Osorio
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share