ladjs / supertest

🕷 Super-agent driven library for testing node.js HTTP servers using a fluent API. Maintained for @forwardemail, @ladjs, @spamscanner, @breejs, @cabinjs, and @lassjs.
MIT License
13.8k stars 757 forks source link

[fix] TypeError: Cannot read properties of undefined (reading 'address') #808

Open salamisodikiolawale opened 1 year ago

salamisodikiolawale commented 1 year ago

Describe the bug

Supertest connot read or find my adress route that i want test Node.js version: v19.0.0

OS version: 22.04

Description: If i use supertest to call pne route of my API i get this error

 FAIL  __test__/movie.test.ts
  Movie
    Hello world route
      Hello world given 404
        ✕ Should be return 404 (1 ms)

  ● Movie › Hello world route › Hello world given 404 › Should be return 404

    TypeError: Cannot read properties of undefined (reading 'address')

      10 |             it("Should be return 404", async() => {
      11 |                 const movieId = 1;
    > 12 |                 supertest(app).get('/api/v1/').expect(404);
         |                                ^
      13 |                 // expect(true).toBe(true);
      14 |             })
      15 |         })

      at Test.serverAddress (node_modules/supertest/lib/test.js:46:22)
      at new Test (node_modules/supertest/lib/test.js:34:14)
      at Object.obj.<computed> [as get] (node_modules/supertest/index.js:43:18)
      at Object.<anonymous> (__test__/movie.test.ts:12:32)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.973 s, estimated 3 s
Ran all test suites. 

Actual behavior

Expected behavior

Code to reproduce

app.ts

import express from 'express';
import cors from 'cors';
import dotenv  from 'dotenv';
import * as mongoose from "mongoose";
import apiRouter from "./router/apiRouter";

//Auto decouvrability
const hateoasLinker = require('express-hateoas-links');

export const app:express.Application = express();

app.use(express.urlencoded({
    extended: true
  }));

app.use(hateoasLinker);

// Configurations
app.use(cors());
dotenv.config( {path : './.env'}); // for env variable
app.use(express.json()); // json form data

let hostName:string|undefined = process.env.HOST_NAME;
let port:number|undefined = Number(process.env.PORT);
let mongoDBUrl:string|undefined = process.env.MONGODB_URL;

// MongoDB connection

if(mongoDBUrl) {
    mongoose.connect(mongoDBUrl).then( () => {
        console.log('Connecting to mongoDB Successfully ...');
    }).catch( (error) => {
        console.log(error);
        process.exit(1); // Stop the node js process
    });
}

app.get('/test', async (request:express.Request, response:express.Response) => {
    response.status(404);
})

// Route Configuration

app.use('/api/v1/', apiRouter);

if(port !== undefined && hostName !== undefined){
    app.listen(port, hostName, () => {
        console.log(`Express Server is running at ${hostName}:${port}`);
    });
}

module.exports= app;

movie.test.ts

import supertest from "supertest";
import {app} from '../app';

describe("Movie", () => {

    describe("Hello world route", () => {

        describe("Hello world given 404", () => {

            it("Should be return 404", async() => {
                const movieId = 1;
                supertest(app).get('/api/v1/').expect(404);
                // expect(true).toBe(true);
            })
        })
    })
})

pacckage.json

{
  "name": "crudmovieservice",
  "version": "1.0.0",
  "description": "",
  "main": "app.ts",
  "scripts": {
    "ts-jest": "ts-jest config:init",
    "test": "jest",
    "start": "nodemon app.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/axios": "^0.14.0",
    "@types/cors": "^2.8.12",
    "@types/express": "^4.17.14",
    "@types/express-validator": "^3.0.0",
    "@types/mongoose": "^5.11.97",
    "@types/node": "^18.7.21",
    "@types/nodemon": "^1.19.2",
    "axios": "^0.27.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.2",
    "express": "^4.18.1",
    "express-hateoas-links": "^1.3.1",
    "express-validator": "^6.14.2",
    "mocha": "^10.1.0",
    "mongodb-memory-server": "^8.10.2",
    "mongoose": "^6.6.1",
    "node": "^18.9.1",
    "nodemon": "^2.0.20",
    "ts-node": "^10.9.1",
    "tsc": "^2.0.4"
  },
  "devDependencies": {
    "@types/jest": "^29.2.5",
    "@types/supertest": "^2.0.12",
    "chai": "^4.3.7",
    "jest": "^29.3.1",
    "supertest": "^6.3.3",
    "ts-jest": "^29.0.3"
  }
}

Checklist

gabrielcipriano commented 1 year ago

Hey, this problem is not related to supertest.

in the last line of your app.ts you exported the app like that: module.exports= app;

when importing it on movie.test.ts, you imported destructuring your app object import {app} from '../app'; when descructuring, this line of code is trying to access the property app from your module.exports, but app is the module.exports itself

the correct syntax would be import app from '../app';