Improving the testing of Express routes using a test database in PostgreSQL

I've been working on improving my skill at writing tests for Node.js APIs, particularly in relation to a recent project where I interact with an endpoint /api/v1/restaurants that provides data in the form of an array of objects. Below is the functional call within the controller:

restaurantRouter.get("/api/v1/restaurants", async (req, res) => {
    try {
        // const results = await db.query("SELECT * FROM restaurants");
        const results = await select("restaurants");

        res.status(200).json({
            status: "success",
            results: results.rows.length,
            data: {
                restaurants: results.rows
            }
        })
    } catch (err) {
        console.log(err)
    }
})
  • In an effort to streamline DB queries, I've separated them into a distinct utility page while still passing the table name "restaurants" as a parameter.
  • On my local drive, both tables restaurants and test_restaurants are operational and exist within the same Database.

An issue arises when attempting to make API calls in my tests using the following method:

        test("restaurants are returned as JSON", async () => {
            await api
                .get("/api/v1/restaurants")
                .expect(200)
                .expect('Content-Type', /application\/json/)
        })

        test("all restaurants are returned", async () => {
            const response = await api.get("/api/v1/restaurants")

            expect(response.body.data).not.toBeEmpty()
            expect(response.body.data.restaurants).toBeArrayOfSize(2)
        })

By default, the tests pull from the Dev database table restaurants. Initially, I considered creating a duplicate route specifically for testing purposes like this:

restaurantRouter.get("/api/v1/test-restaurants", async (req, res) => {
    try {
        const results = await select("test_restaurants");

        res.status(200).json({
            status: "success",
            results: results.rows.length,
            data: {
                restaurants: results.rows
            }
        })
    } catch (err) {
        console.log(err)
    }

})

I am exploring the possibility of utilizing middleware to facilitate passing an optional variable, which defaults to either the Dev or Prod database if no specific parameter is provided. This approach could bring about a more efficient and elegant solution for testing these functionalities.

While researching, I have noticed that many tutorials focus on MongoDB, which appears to offer simpler setups for testing databases. If additional information is required, please let me know. Thank you!

Answer №1

To effectively manage your databases, it is important to distinguish between restaurants and test_restaurants.

Update the test command in your package.json file as follows:

"test": "cross-env NODE_ENV=test jest"
.

Next, configure your app to use the test_restaurants database when the environment variable NODE_ENV is set to test.

if(process.env.NODE_ENV === "test"){
    // use test database
}

if(process.env.NODE_ENV !== "test"){
    // use production database
}


Answer №2

Just wanted to provide some insight into how I implemented @Odunsi's solution:

In my db/index.js file:

const { Pool } = require("pg")

const PG_DATABASE = process.env.NODE_ENV === "test" 
? process.env.TEST_DATABASE 
: process.env.DEV_DATABASE


const pool = new Pool({
    user: process.env.PGUSER,
    host: process.env.PGHOST,
    database: PG_DATABASE,
    port: 5432,
    password: null
})

pool.on('connect', () => {
    console.log(`Connected to the DB: ${process.env.NODE_ENV}`);
});

module.exports = {
    query: (text, params) => pool.query(text, params)
}

The key was including the NODE_ENV environment variable in the scripts (as mentioned in the previous response), but I managed without having to use the cross-env module.

"scripts": {
    "test": "NODE_ENV=test jest --verbose --runInBand",
    "dev": "NODE_ENV=development nodemon index.js"
  },

I am now able to work with two separate databases seamlessly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Authentication is necessary for the "insert" command when establishing a connection to a remote database server | error code: 13, error code name

I have successfully established a connection to the remote server const express =require("express"); const bodyParser = require("body-parser"); const mongoose = require("mongoose"); const Promise = require(&apo ...

Tips for effectively structuring express routes

Struggling to understand how to effectively utilize the /:variable notation. My current setup includes this layout: router.route("/").get() router.route("/:id").get().put().post().delete() router.route("/auth").get().put().pos ...

Guide on routing a websocket connection through a proxy server

Encountering an issue with github.com/facebook/create-react-app, particularly when proxying the webpack-dev-server with a custom server. While HTTP requests work fine, WebSocket requests fail with this specific error: WebSocket connection to 'ws://l ...

Generating various API calls and delivering them to a template (Express + Node.js + Facebook open graph)

I am currently developing a unique Express Node.js application that utilizes the extraordinary capabilities of this remarkable Facebook SDK. Allow me to present my existing route for the root: app.get('/', Facebook.loginRequired(), function (req ...

Tips for locating an element beyond the page source with Puppeteer

My goal is to extract specific information from a webpage by utilizing this code snippet to target an element and retrieve certain values within it: const puppeteer = require('puppeteer'); function run (numberOfPages) { return new Promise(a ...

Encountering 404 Errors while Attempting to Reach API Endpoint in an Express.js Application Hosted on cPanel

I have a Node.js application running on cPanel, and I'm facing 404 errors when trying to access an API endpoint within my app. Let me provide you with the setup details: Directory Structure: public_html/ server.mjs index.html node_modules ...

Implementing a notification system similar to Stack Overflow in a Node.js and MongoDB application

Apologies if my inquiry seems vague, but let me explain my situation. I have a forum similar to StackOverflow, built on nodejs and mongodb. The forum includes posts and comments. I am in need of implementing a notification system that alerts users when a n ...

Optimal method for saving authenticated user in redux state

I am currently working on developing an application with the following technologies: Next.js An Express API Redux-Toolkit and RTK Query All of the authentication logic has been implemented successfully, but I have encountered a problem. After a successf ...

Setting up NestJs with TypeORM by utilizing environment files

In my setup, I have two different .env files named dev.env and staging.env. My database ORM is typeorm. I am seeking guidance on how to configure typeorm to read the appropriate config file whenever I launch the application. Currently, I am encountering ...

The requested resource does not contain the 'Access-Control-Allow-Origin' header. It has already been included in the headers

Despite adding the 'Access-Control-Allow-Origin': '*' header to my Axios request, I am still encountering the same error. When trying to access 'http://backendUrlEndPoint' from origin 'https://frontendURL', the COR ...

Get started with Npm Install directly from the package.json configuration file

I'm struggling to find the answer to a question that seems pretty straightforward. I've successfully cloned a git repo onto my computer. But now, when I try to start node, I'm getting an error because I haven't installed the necessary ...

Encountering issues with Next.js routing - Pages failing to load as expected

Having some trouble with the routing in my Next.js application. I've created a page named about.tsx within the "pages" directory, but when trying to access it via its URL (localhost:3000/about), the page fails to load correctly and displays: This Pa ...

Easily integrating a JavaScript file into an HTML document when utilizing a NodeJS Express server

Currently in the process of developing a chat application, utilizing the Express server with NodeJS and AngularJS for client-side management. Encountering an issue when attempting to include /js/code.js in my html, as it cannot be found due to not being p ...

Invoking a C++ dll in the renderer process of a Node.js application with Electron using node ffi

As I work on developing a windows application using electron, my goal is to utilize the ffi-napi to invoke C++ .dll methods. However, I am facing a challenge with the "Passing_Dll.js" file, where the label with id "GenName" is not being updated when clicki ...

Utilizing cloud functions to distort an inappropriate image

I have a requirement to analyze any uploaded image for inappropriate content and blur it if necessary. The log this image is inappropriate indicates that the detection process is working correctly. However, I am not able to see any further logs which sugg ...

Error in Docker: Unable to resolve due to sender error: context has been terminated

After attempting to build my docker image for the project in VS Code terminal, I ran into an error. What are some possible reasons for this issue? Along with this question, I have also shared a screenshot of the error logs. ERROR: failed to solve: error ...

Failed to connect to the server using socket `/var/run/postgresql/.s.PGSQL.5432` due to the file or directory not existing

Struggling to deploy my new app on heroku and can't seem to find a solution. The following error keeps popping up: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory. Is the server running l ...

acquire the JWToken using Cypress and establish it as the header for subsequent requests

While attempting to test an Express web application I developed, the first step is authentication to retrieve a JWT token. The token retrieval process works fine, but when trying to set the header for subsequent requests, it doesn't seem to work. Thi ...

The JSON data structure is not being maintained

I am facing an issue with updating the json object model values using the code below. Even after changing the values, it seems like the model is not getting updated. I tried removing the async code and that worked. Why does the async code not work in this ...

Encountered a problem while trying to install Angular CLI using npm

My current version of node js is 8.9.2 and I encountered an issue while trying to install Angular CLI. When running this command: npm -g install @angular/cli I received npm errors that stopped the installation process. Here's the error message show ...