codingwithmanny
codingwithmanny

Reputation: 1184

How do you test NodeJS to see if a middleware was used?

Forgive me if this is something you shouldn't do, but I've looked around to see what is possible.

I want to verify that my express app has a middleware called/used for the app.

import express from 'express';
import cors from 'cors';

const app = express();

app.use(cors()); // <----- I WANT TO TEST THIS

app.get('/', (_req, res) => res.send({ hello: 'world' });

app.listen(5000, () => console.log(`Listening on port 5000`));

export default app;

Potential jest test

import app from './index.ts';

// This is a poor attempt to try and get this to work
test('test if CORS is implemented', () => {
   const mockCors = jest.mock('cors');

   const myApp = app;

   expect(mockCors).toHaveBeenCalledTimes(1);
});

If anyone has the solution and if I should not be doing this, what is the reason behind it?

Upvotes: 0

Views: 1772

Answers (1)

blex
blex

Reputation: 25634

My guess is that you don't actually care that cors is called. Your client won't say to you "I want the cors middleware to be called". All the client should care about is the service that is provided, not how it's implemented. Your tests should do the same. If you decide one day to use another module for CORS, your tests shouldn't need to change, why would they?

My (personal) preferred approach is exactly that. Testing that given some input, my programs gives me the output I desire. Everything inside the program can be changed, as long as the behavior does not change. That will give you peace of mind when refactoring.

Also, for testing an Express app, you don't need a server, you just need the app. Actually starting the server can add complexity to your tests, since they might be hanging if you forget to close the server after them.

So in this example, the very first thing I would do is move everything you have in index.ts into a file called app.ts, and remove this line:

app.listen(5000, () => console.log(`Listening on port 5000`));

And in index.ts, only have this:

import app from './app.ts';
// Start the server
app.listen(5000, () => console.log(`Listening on port 5000`));

Then, I would use Supertest along with Jest, to make requests to that app:

npm i -D supertest

And then, in your test file, test what matters to the client:

import request from 'supertest';
import app from './app.js'; // Just import the app, not the server

describe("myApp", () => {
  it('should implement CORS', async() => {
    const { headers } = await request(app).get('/');
    expect(headers['access-control-allow-origin']).toEqual('*');
  });
});

Upvotes: 4

Related Questions