supertest icon indicating copy to clipboard operation
supertest copied to clipboard

TypeError: Cannot read property 'address' of undefined

Open voiddeveloper opened this issue 4 years ago • 10 comments

I created an express.js server with ts and tried to test it, but got an error. I can't find a solution no matter how I search.

server.ts

import App from './app';
import PostsRouter from './routes/posts';

export const app = new App(
    [
        new PostsRouter(),
    ],
    3000,
).listen();

app.ts

import * as express from 'express';

class App {
    public app: express.Application;
    public port: number;

    constructor(controllers: any[], port: number) {
        this.app = express();
        this.port = port;

        this.initializeControllers(controllers);
    }

    private initializeControllers(controllers: any[]) {
        controllers.forEach((controller) => {
            this.app.use('/', controller.router);
        });
    }

    public listen() {
        this.app.listen(this.port, () => {
            console.log(`App listening on the port ${this.port}`);
        });
    }
}

export default App;

posts.spec.ts

import * as request from "supertest";
import { app } from "../server";


describe("GET /posts", () => {
    it("respond with json", async done => {
        await request(app)
            .get("/posts")
            .set("Accept", "application/json")
            .expect("Content-Type", /json/)
            .expect(200, done);
    });
});

Screen Shot 2020-03-03 at 7 47 26 AM

voiddeveloper avatar Mar 02 '20 22:03 voiddeveloper

Having the exact same issue...

matheuseabra avatar Mar 10 '20 13:03 matheuseabra

@voiddeveloper Your custom .listen method needs to return the express application*.

jonathansamines avatar Mar 14 '20 01:03 jonathansamines

im having the same issue but with e2e test... any news?

lucasguiss avatar Mar 19 '20 23:03 lucasguiss

i have this issue with e2e test too!

mmRoshani avatar Mar 28 '20 03:03 mmRoshani

@voiddeveloper I was also facing the same issue, this should work

posts.spec.ts

import * as request from "supertest";
import App from '../app';
import PostsRouter from '../routes/posts';

// This will return the express application 
const api = request(new App([
        new PostsRouter(),
    ],
    3000).app);

describe("GET /posts", () => {
    it("respond with json", async done => {
        await api
            .get("/posts")
            .set("Accept", "application/json")
            .expect("Content-Type", /json/)
            .expect(200, done);
    });
});

iamdarshanshah avatar Apr 09 '20 11:04 iamdarshanshah

I have this same issue too..

HADMARINE avatar Apr 29 '20 03:04 HADMARINE

@voiddeveloper Your custom .listen method needs to return the express application*.

Is there any method to use supertest without returning express application?

HADMARINE avatar Apr 29 '20 04:04 HADMARINE

It can be fixed by giving "http.Server" type parameter to request function. therefore, app.ts should return http.Server to solve that problem. @voiddeveloper

HADMARINE avatar Apr 29 '20 05:04 HADMARINE

I have the same issue because i forgot to mention module.exports = app in app.js but my folder structure is different here is my folder structure app.js

const http = require("http");
const express = require("express");

const app = express();
const server = http.Server(app);

app.post("/example", function (request, response) {
    // my router logic
});

server.listen(process.env.PORT || 3000, process.env.IP || "0.0.0.0", () => {
  console.log("Server running");
});
module.exports = app

test/app.test.js

const app = require("../app.js"); // runs app.js
const request = require("supertest"); // needed to make API requests

describe("When the example router  is running", () => {
  // Add individual test cases
});

mirsahib avatar Jan 02 '21 16:01 mirsahib

To solve this you need to pass a string to the request method... something like this:

import * as request from "supertest";
import { server } from "../server";

const API = 'http://localhost:3000';

describe("GET /posts", () => {
    it("respond with json", async done => {
        await request(API)
            .get("/posts")
            .set("Accept", "application/json")
            .expect("Content-Type", /json/)
            .expect(200, done);
    });
});

iszlailorand avatar Mar 16 '23 13:03 iszlailorand