I have built the initial configuration of my API and am trying to use Jest and Supertest to set up testing.
Despite extensive searching through Stack Overflow and through supertest documentation I have been unable to resolve this error:
TypeError: app.address is not a function
I realize I need to export my server into the Jest testing script and thought that is what I managed to do by setting my app.listen to server and exporting that as that is what was found in related solutions, but it did not work here.
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const cors = require('cors');
const pool = require('./db');
const verifyToken = require('./helpers/verifyToken');
const { ppid } = require('process');
const PORT = process.env.PORT || 5000;
//process.env.PORT
// Middleware
app.use(cors());
app.use(express.json());
// API ROUTES
var user = require('./routes/user');
var contact = require('./routes/contact');
var organization = require('./routes/organization');
var group = require('./routes/group');
app.use('/user', user);
app.use('/contact', contact);
app.use('/organization', organization);
app.use('/group', group);
// PAGE ROUTES
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
app.get('/home', (req, res) => {
res.sendFile(path.join(__dirname + '/public/home.html'));
});
app.get('*', (req, res) => {
res.status(400).send({ error: 'Incorrect Endpoint' });
});
// EXPRESS START
const server = app.listen(PORT, () => {
console.log(`Server has started on port ${PORT}`);
});
module.exports = { server };
// All User Related Routes
const express = require('express');
const pool = require('../db');
const verifyToken = require('../helpers/verifyToken');
const generateToken = require('../helpers/generateToken');
const jwt = require('jsonwebtoken');
const router = express.Router();
// Get All Users or User By ID
router.get('/:id?', verifyToken, async (req, res) => {
const { id } = req.query;
try {
if (id) {
const { id } = req.query;
const getUser = await pool.query('SELECT * FROM users WHERE id = $1', [
id,
]);
res.json(getUser.rows);
} else {
const getUser = await pool.query('SELECT * FROM users');
res.json(getUser.rows);
}
} catch (err) {
console.log(err.message);
}
});
module.exports = router;
const request = require('supertest');
const app = require('../index');
describe('GET /user', function () {
it('responds with json', function (done) {
request(app)
.get('/user')
.auth('username', 'password')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done);
});
});
● Cannot log after tests are done. Did you forget to wait for something async in your test?
Attempted to log "Server has started on port 5000".
at CustomConsole.log (../../../../usr/local/lib/node_modules/jest/node_modules/@jest/console/build/CustomConsole.js:186:10)
at Server.<anonymous> (index.js:55:11)
FAIL __tests__/first.test.js
GET /user
✕ responds with json (2 ms)
● GET /user › responds with json
TypeError: app.address is not a function
5 | it('responds with json', function (done) {
6 | request(app)
> 7 | .get('/user')
| ^
8 | .auth('username', 'password')
9 | .set('Accept', 'application/json')
10 | .expect('Content-Type', /json/)
at Test.serverAddress (node_modules/supertest/lib/test.js:55:18)
at new Test (node_modules/supertest/lib/test.js:36:12)
at Object.get (node_modules/supertest/index.js:25:14)
at Object.<anonymous> (__tests__/first.test.js:7:8)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.486 s
Ran all test suites.
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.
When you test with supertest, it create its own virtual connection. So it just requires an app instance, not a server instance (server is the app listening on a port). So what you need to do is separate your server into another file, server.js:
The content of server.js will be:
const app = require('./index.js');
const PORT = process.env.PORT || 5000;
const server = app.listen(PORT, () => {
console.log(`Server has started on port ${PORT}`);
});
module.exports = { server };
And content index.js will be:
...
...
...
app.get('*', (req, res) => {
res.status(400).send({ error: 'Incorrect Endpoint' });
});
module.exports = app;