Unable to test with Jest
I been trying to write some test with using using OpenAPI 2.0, I'm using this library to add the paths via the controllers but I always get a 404 response back from the tests,
Here is my openapi.json
{
"swagger": "2.0",
"info": {
"version": "0.0.1",
"title": "Restaurant",
"description": "API for Restaurant Platform"
},
"host": "localhost:9000",
"basePath": "/api/v1",
"schemes": ["http", "https"],
"securityDefinitions": {
"Bearer": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
},
"consumes": ["application/json"],
"produces": ["application/json"],
"paths": {},
"definitions": {
"Message": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
this is my controller message.js
const get = [
(req, res) => {
res.status(200).json({ message: 'Hello World!!!' });
},
];
get.apiDoc = {
operationId: 'getMessage',
summary: 'Get the api message.',
description: 'Returns the hello world message.',
tags: ['Message'],
responses: {
200: {
description: 'The hello world message',
schema: {
$ref: '#/definitions/Message',
},
},
},
};
module.exports = {
get,
};
and here is my app.js config
import 'dotenv/config';
import logger from 'morgan';
import path from 'path';
import { initialize } from 'express-openapi';
import express from 'express';
import passport from 'passport';
import cors from 'cors';
import authMiddleware from './middlewares/auth';
import { connect } from '../mappings';
import openapi from './openapi.json';
/**
* Connecting to the Database
*/
connect.then();
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(logger('dev'));
app.use(passport.initialize());
app.use(authMiddleware);
/**
* Initialize the openapi
* @param app - The express app instance
* @param {Object} apiDoc - The js/json file with our base api declaration
* @param {String} paths - The path to the routes
* @param {Boolean} validateApiDoc - Allow validation of the api definition document
* @param {String} docsPath - Endpoint for the api definition BASEURL + /openapi.json
* @param {Function} errorMiddleware - Custom middleware to manage commons error
*/
initialize({
app,
apiDoc: openapi,
paths: path.resolve(__dirname, 'controllers/v1'),
validateApiDoc: true,
docsPath: '/openapi.json',
errorMiddleware(err, req, res) {
logger.error(err, 'error-handler');
if (!err.status || err.status === 500) return res.status(500).send();
return res.status(err.status).json(err.errors);
},
});
export default app;
as for my test I only have the following
import path from 'path';
import jestOpenAPI from 'jest-openapi';
import request from 'supertest';
import app from '../app';
jestOpenAPI(path.join(__dirname, '../openapi.json'));
describe('message', () => {
it('should make a GET request and satisfy OpenAPI spec', async () => {
// Make request (supertest used here)
const res = await request(app).get('/message');
// Make any assertions as normal
expect(res.status).toEqual(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).toSatisfyApiSpec();
});
});
here is the console output.

We have this issue too. Your call to initialize() returns a promise. So that's why you are getting a 404 – the routes aren't yet configured. You can verify this by debugging and inspecting app._router.stack.
However, my problem is that my test just seems to hang when importing my app.js file with an initialize() call. As soon as I comment out initialize() in app.js, I get the same result as OP, 404s.
bump
Hey checkout jest-light-runner @itswoop & @hggonzalez we found that adding in a block to our pkg.json with the following code:
"runner": "jest-light-runner"
}```
also run an npm install for https://www.npmjs.com/package/jest-light-runner
`npm i jest-light-runner` we are on Node 16.17 and everything is working for us.
Might be related.
I got an issue with OAS 3.0. Jest returns the following error:
Test suite failed to run
A jest worker process (pid=46310) was terminated by another process: signal=SIGSEGV, exitCode=null. Operating system logs may contain more information on why this occurred.
at ChildProcessWorker._onExit (node_modules/jest-worker/build/workers/ChildProcessWorker.js:366:23)
The error will go away if I comment out initialize() in app.js.
The Jest crash has something to do with the following two configuration fields:
await initialize({
...
routesGlob: "**/*.{ts,js}",
routesIndexFileRegExp: /(?:index)?\.[tj]s$/,
...
});
If I comment them out to use default one, it seems not able to generate path correctly (got 404 instead of 200):
● GET /v2/todos › should return 200 for todos get request
expect(received).toEqual(expected) // deep equality
Expected: 200
Received: 404
110 | it('should return 200 for todos get request', async () => {
111 | const res = await req.get('/v2/todos');
112 | expect(res.statusCode).toEqual(200);
Update: the reason why it got 404, because paths isn't populated since the following test case is passing:
describe('Get /v2/api-docs', () => {
it('should return 200 for api docs request', async () => {
const res = await req.get('/v2/api-docs');
expect(res.statusCode).toEqual(200);
//prove supertest not working with express-openapi since paths not populated
expect(res.body.paths).toEqual({});
});
});
@mwithington: It is working with jest-light-runner as suggested by you against js files instead the ones ts-jest transformed from ts files.
So it appears to be typescript related problem when working express-open-api and supertest together.