Strategies for testing a split get() function using expressJS and jestJS to streamline unit testing

How can I define a get() route in an Express.js application for easy unit testing?

To start, I extracted the get() function into its own file:

index.js

const express = require('express')
const socketIo = require('socket.io')
const Gpio = require('pigpio').Gpio

const app = express()
const server = http.createServer(app)
const io = socketIo(server)

const setStatus = require('./lib/setStatus.js')

app.locals['target1'] = new Gpio(1, { mode: Gpio.OUTPUT })

app.get('/set-status', setStatus(app, io))

lib/setStatus.js

const getStatus = require('./getStatus.js')

module.exports = (app, io) => {
  return (req, res) => {
    const { id, value } = req.query
    req.app.locals['target' + id].pwmWrite(value)
    getStatus(app, io)
    res.send({ value })
  }
}

lib/getStatus.js

const pins = require('../config.js').pins

module.exports = async (app, socket) => {
  const result = []
  pins.map((pin, index) => {
    result.push(app.locals['target' + (index + 1)].getPwmDutyCycle())
  })
  socket.emit('gpioStatus', result)
}

I'm unsure if I separated the code correctly for unit testing purposes.

When calling /set-status?id=1&value=50, the expected action is to call pwmWrite() on an object defined by new Gpio stored in Express.js locals.

However, I'm uncertain how to write a Jest unit test to verify the internal call to pwmWrite within an asynchronous function.

This is my current attempt, but I'm struggling to test the pwmWrite call inside an async function:

test('should call pwmWrite() and getStatus()', async () => {
  const app = {}
  const io = { emit: jest.fn() }
  const req = {
    app: {
      locals: {
        target1: { pwmWrite: jest.fn() }
        }
      }
    }
  }
  expect.assertions(1)
  expect(req.app.locals.target1.pwmWrite).toHaveBeenCalled()
  await expect(getStatus(app, io)).toHaveBeenCalled()
})

Answer №1

You are on the right track, but there are a few key elements missing.

In order for your test to work properly, make sure to include the setStatus and getStatus methods before the expect statements. Additionally, don't forget to add mocks for req.query and res, as getStatus relies on them.

test('should call pwmWrite() and getStatus()', async () => {
  const app = {}
  const io = {};
  const req = {
    query: {
      id: '1',
      name: 'foo'
    },
    app: {
      locals: {
          target1: { pwmWrite: jest.fn() }
      }
    }
  };
  const res = { send: jest.fn() };

  // Mock getStatus BEFORE requiring setStatus
  jest.mock('./getStatus');

  //Make sure to use the correct module paths
  const setStatus = require('./setStatus');
  const getStatus = require('./getStatus');


  // Call methods
  setStatus(app, io)(req, res);

  expect.assertions(2);

  // Check if pwmWrite is called in setStatus
  expect(req.app.locals.target1.pwmWrite).toHaveBeenCalled();

  // Verify that mocked getStatus has been called
  await expect(getStatus).toHaveBeenCalled();
});

Remember to mock getStatus before requiring setStatus, as it is needed within the code.

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

Cannot be iterated upon when utilizing the find ObjectId operation

I'm attempting to locate a specific document in my MongoDB and then update its integer value using a find query. I am utilizing $in because I used an array to search for each element within it, but when I used ObjectId it is throwing an error: bloo ...

unable to utilize references in React

import React, { Component } from "react"; class Learning extends Component { firstName = React.createRef(); handleSubmit = event => { event.preventDefault(); console.log(this.firstName.current.value); } ...

Utilizing AJAX Crawling in combination with Express for navigating static routes

My website has a static route set up for /public/slides/lecture1.html#!3 This route displays the third div element from lecture1.html, with other div elements having display:none;. I am currently using Express and the code app.use(express.static(WEBROOT ...

The difference between using document.getElementsByTagName("img") and document.getElementById('testimg')

My HTML code is as follows: <a href="index.php"><img id="testimg" src="images/logo.png"/></a> This is my JavaScript code: function getW(){ var theImg = document.getElementById('testimg'); return theImg; } theImg = ...

VueJS Unit Testing: Exploring the Content of Attributes- What to Test?

I'm currently facing some challenges with my initial VueJS unit tests using Jest. Although I grasp the concept and have already executed my first set of successful tests, I find myself pondering over the question of "What aspects should I test?" For ...

Res.redirect is failing to redirect and displaying error message 'Connection Unavailable'

Currently, I am in the process of developing a NodeJS + ExpressJS Ecommerce Website. My focus is on enhancing the functionality of the admin panel feature. Users can navigate to /admin/products/new to access a form. When the user completes and submits this ...

Angular ng-repeat is incompatible with the JSON parser

I am facing an issue with accessing JSON objects and setting values into Angular Ui-grid. The problem arises when some of the fields in my JSON object are actually JSON strings. I attempted to convert these fields into JSON objects using JSON.parser, but e ...

Is there a reliable method for parsing a CSV file that contains JSON strings as values?

When parsing CSV files, I encountered values that include strings representing JSON objects, along with boolean, normal strings, and other data. The CSV file has a header, and as I loop through the non-header rows, I utilize Javascript's split method ...

How can data be transferred from a parent component to a child component using MaterialUI's styling functionality?

Recently delving into the world of reactjs, I've been tinkering with a basic page that incorporates authentication using state. To spruce up the design, I decided to use the MaterialUI framework. The issue I'm facing is related to sending the lo ...

Encountering an error with loading %5Bobject%20Object%5D on a webpack-generated JavaScript file hosted in an express server because of Stylus styles

I have been experimenting with enhancing the example linked here. Initially, everything worked smoothly when I used npm start. However, I wanted to integrate it into an existing ExpressJS project. To achieve this quickly, I copied the three js files to the ...

What is the best way to retrieve a single item from an array stored in MongoDB using a query?

Recently diving into MongoDB/Mongoose while utilizing MongoDB, Node, and Express. Wondering how to query and fetch a single item from an array in MongoDB. Here's the database structure: { "id" : ObjectId("5e19d76fa45abb5d4d50c1d3"), "na ...

How can I add a channel to a category using await(discord.js)?

Having trouble organizing a new channel within a category. The .setParent(categoryID) method seems to only work with existing channels, causing an issue when I attempt to execute my code. Take a look at the code snippet below: client.on("message" ...

The initial AJAX GET request is successful, however subsequent clicks do not trigger the call

I have been encountering an issue with my JavaScript where an Ajax call that used to work perfectly fine suddenly stopped working. I have not made any changes to the code that could cause this problem, but something is definitely going wrong. The Ajax call ...

The error message "Type 'string | number' is not assignable to type 'number'" indicates a type mismatch in the code, where a value can be either

I encountered an error code while working with AngularJS to create a countdown timer. Can someone please assist me? //Rounding the remainders obtained above to the nearest whole number intervalinsecond = (intervalinsecond < 10) ? "0" + intervalinseco ...

What is causing the issue preventing me from running npm run dev on CentOS 7?

Currently facing an issue while trying to install my application on a new server after migrating from centos6 to centos7. When attempting to install a Laravel app, everything goes smoothly as it did on centos6, except for when I run npm run dev [root@v6-a ...

The eccentricities of Angular Translate in Firefox and Safari

While everything functions correctly in Chrome, there seems to be an issue with changing the language in Safari and Firefox. angular.module('angularApp') .config(['$translateProvider', function ($translateProvider) { $translateProv ...

What is the best way to populate MongoDB with information retrieved from an external API?

Recently, I've been diving into the world of NodeJS with mongoose & mLab. As someone new to these technologies, I'm slowly piecing together my model. Here's what it looks like for now, with plans to expand the schema down the road. cons ...

Is there a Page Views tracker in sinatra?

Help needed with implementing a page views counter using Sinatra and Ruby. I attempted using the @@ variables, but they keep resetting to zero every time the page is reloaded... Here's an example: Appreciate any advice! ...

Looking for a way to extract Regular Expressions from an IgGrid cell in Infragistics?

Is it possible to apply a regular expression to a igTextEditor within an igGrid Updating? I attempted to utilize the validate option, but it was unsuccessful. $("#schedulerTable").igGrid({ columns: $scope.schedulerColumns, widt ...

Error: Unable to locate module during module creation

I encountered an error while trying to import a module in my test application. ../fetchModule/index.js Module not found: Can't resolve './Myfetch' in '/Users/******/nodework/fetchModule' Here is the folder structure: https:/ ...