Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually scrutinized for proper operation. In this guide, we will walk through an example of unit testing in Node.js using the NestJS framework. We will focus on testing a BookService class, covering its methods for creating, retrieving, updating and deleting books while demonstrating best practices for testing.
Before diving into unit testing, make sure you have a basic understanding of Node.js, NestJS, Jest and MongoDB.
To begin, let's set up the environment by creating a book.service.ts file. Additionally, we'll install and import all necessary dependencies and construct a BookService class.
Next, proceed to develop a function for generating a new book entry using MongoDB and the Mongoose library.
Then, develop a function to find a book by its id.
Similarly, create a function to update a book.
Finally, create a function to delete a book.
Now, as we delve into the unit testing process for the BookService class, our aim is to ensure that each function operates precisely as intended.
First create a book.service.spec.ts file in the same directory as the book.service file.
In unit testing for NestJS, the Test and TestingModule classes from @nestjs/testing establish the testing environment. To simulate database interactions, the getModelToken function from @nestjs/mongoose is employed. Through the jest.fn() function, a mock BookService instance is created to track method calls. This mock service and a simulated database model are provided by configuring the testing module using getModelToken(Book.name). After compilation, the BookService instance and model are accessed using the module.get() method.
In this test scenario, we create a mock object that simulates a new book. We then set up a mock implementation of the create function within the model to resolve with our predefined mock book. By calling the create function of our service with the mock book data, we ensure that the service responds as anticipated. The expect statement confirms that the result corresponds to our predefined mock book, thereby validating the correctness of the create function. Also initialize all the required dependencies.
For this test scenario, we begin by importing essential dependencies and creating a mockBook object. This object will serve as a placeholder for simulating a book's attributes and properties during our tests.
Then we thoroughly test findById function. We have declared three test cases.
The first test case ensures that the function correctly finds and returns a book by its ID. We achieve this by mocking the model's findById function to resolve with our predefined mock book, and then verifying if the result matches the expectation.
The subsequent test cases handle error scenarios. In the second test case, we simulate an invalid ID and assert that calling findById with this ID triggers a BadRequestException. We achieve this by mocking the isValidObjectId function to return false and then using expect to confirm the thrown error.
The third test case tests the condition where the findById function cannot find the requested book. We mock the model's findById function to return null, simulating a scenario where the book is not found. As expected, we then verify if calling findById with this ID raises a NotFoundException.
By testing these different scenarios, we ensure that our findById function behaves correctly and handles exceptions as intended.
In this test scenario, we verify the functionality of updating and returning a book's information. The test scenario involves simulating the update of a book's title and confirming that the updated book object is returned as expected.
During the test execution, the service's 'updateById' function is called with the relevant book ID and the updated book data. The mock implementation ensures that the service interacts with the model's 'findByIdAndUpdate' method as intended.
The test ensures that the "deleteById" function successfully deletes a book and returns the expected result. By mocking the database operation using "findByIdAndDelete," we verify that the function interacts correctly with the data model.
After completing our test scenarios to cover various aspects of our application's functionality, it's time to see them in action.
Must ensure that you are in the root directory of your Nest.js project, follow these steps:
- Open your terminal or command prompt.
- Enter the following command: npm run test
This command initiates the execution of your unit tests using the testing framework we set up earlier.
Running the tests is a crucial step in ensuring the reliability and correctness of your code base.
Throughout this guide, we explored the core concepts of unit testing in NestJS, including the setup of testing modules, the creation of mock services, and the execution of test cases.
Ehsaan Technologies is a Software Development & Consultancy firm providing customized Web development and Mobile App development services to its customers across the Globe.