< Back to Blog > ​Product & ​Engineering > Testing With Persistence in NestJS

Testing With Persistence in NestJS

Testing With Persistence in NestJS
August 21, 2022 | 6mins Read

At Spinwheel, we use Nest for platform development. Nest (NestJS) is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with and fully supports TypeScript (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Nest provides a very good end to end testing mechanism with Jest. It is facilitated for the same via the @nestjs/testing module. 

Spinwheel focuses on end to end testing as part of its development flow. 

When originally setting up end-to-end testing on the platform, we faced four core problems. I’ll walk you through how we solved each of these problems. 

Problem: Connecting to external persistent systems like database and queues while testing

Solution: Starting the application in a test environment with external dependencies 

  • For any API, it needs to talk to a database to read or write persistent data. As part of end-to-end test setup, we had to make sure we were able to connect to the database when we bootstrapped the application for testing. 
  • The solution we came up with is instrumenting mongodb-memory-server as a module. One of the problems with any persistence layer is it needs to be running or available before executing tests. Since we use the NestJS framework,  we wrapped the in-memory server into a module which helped us tap into the applications start and shutdown behavior. This ensures that we have persistence available before executing tests after starting an application. We used the modules lifecycle events to start accurately before execution of tests to be available for tests. It exposed a service which could share the connection URI which can be used in the “application” we are testing. 
  • We use queues in the platform to get asynchronous tasks done. To stop the application from failing due to connection issues in the testing environment and also facilitate real messages for the purpose of testing functionality, we mocked the queue connector module. We then created a fixture to support the NextJS transport layer required to support queue communication. 
  • This allowed us to post and receive messages in memory for the edge to edge testing of our controllers, decorators including authentication and filtering and interceptors. 

Problem: Creating necessary objects in DB to test with real scenarios

Solution: Providing a context to test case 

  • To create the relevant objects in db for simulation of scenarios we used factory. Wrote factories for DTOs to generate the JSON objects and saved them in memory DB before each test scenario mentioned above.

Problem: Calling endpoints for bootstrapped application

Solution: Testing APIs

  • We have an HTTP server to expose an API on the platform. To test that we used supertest to call endpoints. 
  • We also used the fixture we created to send the messages via in-memory queue to invoke the controllers for microsservice listeners. 

Problem: Mocking external systems like API calls and loggers

Solution: Supporting integrations

  • We used nock for mocking the HTTP requests going out of the system to provide pre-saved objects. 

This article was written by Bharat MhaskarRonan Fegan and Alejandro Mouras did the hard work of increasing our coverage from nothing to majorly covered code, implementing all the solutions mentioned above.

spinwheel

About the author: Spinwheel is on a mission to make it easier to manage debt. Our Loan APIs make it easy to embed consumer loan data, including credit card debt, student loans, personal loans, auto loans, and mortgages, directly into your app or product. With just one connection, you'll be able to help your business and your users improve financial outcomes. We call this Better Debt. Read More >

Related Articles