How do I define a get() routing in an expressJS application with the intention of doing easy unit testing?
So as a first step I moved the function of get()
in an 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 // id is in this example '1'
req.app.locals['target' + id].pwmWrite(value))
getStatus(app, io)
res.send({ value }) // don't need this
}
}
lib/getStatus.js
const pins = require('../config.js').pins
module.exports = async (app, socket) => {
const res = []
pins.map((p, index) => {
res.push(app.locals['target' + (index + 1)].getPwmDutyCycle())
})
socket.emit('gpioStatus', res)
}
So first of all I'm not quite sure, if I split that code correctly - thinking of doing unit testing.
For me the only thing which has to be done by calling /set-status?id=1&value=50
is to call pwmWrite()
for an (I guess) object, which is defined by new Gpio
and stored in locals
of expressJS.
And for the second: If this should be the correct way, I do not understand how to write a jestJS unit test to check if pwmWrite
has been called - which is inside of an asyncronous function.
This is my attempt, but I can't test for the inside call of pwmWrite:
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()
})
You are very close, just missing a few things.
You need to call the methods setStatus
and getStatus
before the expect statements,
and you were missing mocks on req.query
and res
, since getStatus
uses 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');
//OBS Use your correct module paths
const setStatus = require('./setStatus');
const getStatus = require('./getStatus');
// Call methods
setStatus(app, io)(req, res);
expect.assertions(2);
// Get called in setStatus
expect(req.app.locals.target1.pwmWrite).toHaveBeenCalled();
// See if mocked getStatus has been called
await expect(getStatus).toHaveBeenCalled();
});
The getStatus
needs to be mocked before requiring setStatus
, since its used there
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With