TypeScript + Mocha + Express-TypeError:app.address不是函数

时间:2019-06-20 22:57:10

标签: javascript node.js typescript express mocha

在将API从ES6转换为TypeScript时,尝试针对Express REST端点运行单元测试时遇到了这个问题:

TypeError: Cannot read property 'address' of undefined

我已经重新安排了一些代码来加载服务器,但是基本上是这样的:

server.ts

import App from './app';

...bunch of imports...

new App([..., new Controller()]);

app.ts

export default class App {
    constructor(controllers) {
        this.app = express();

        this.initControllers(controllers);
    }

    initControllers(controllers) {
        controllers.forEach((controller) => {
            controller.setupRoutes(this.app);
        }
    }

}

然后每个Controller至少由setupRoutes()函数组成,看起来像这样:

setupRoutes(app: Application): void {
    app.get(`/myRoute`, this.heartbeat);
}

当尝试在Spec文件(仍为JS)中调用路由时,我同时导入了../../build/app.js../../build/server.js文件。进入超级测试,结果如下:

const server = require('../../build/server.js');
const app = require('../../build/app.js');

let supertest = require('supertest')(app);
产量TypeError: app.address is not a function

let supertest = require('supertest')(app.default);
产量Uncaught TypeError: Class constructor App cannot be invoked without 'new'

测试本身只是ES6,而不是TS。我现在还不打算将测试转换为TS,并且现在仍想对其使用ES6。

1 个答案:

答案 0 :(得分:1)

您必须将http.Server或Express应用传递给supertest,您的appconst app = require('../../build/app.js');)只是一个包装类。

您需要传递给supertest的是appInstance.app

我的建议:

在您的应用中将Express实例公开:

export default class App {
  constructor(controllers) {
    this.app = express();

    this.initControllers(controllers);
  }

  initControllers(controllers) {
    controllers.forEach((controller) => {
      controller.setupRoutes(this.app);
    });
  }

  // express instance getter
  getExpressInstance(): Application {
    return this.app;
  }

}

然后,您必须在server.ts中导出App实例:

import App from './app';

...bunch of imports...

const app = new App([..., new Controller()]);

export default app;

最后,在您的supertest文件中:

const AppInstance = require('../../build/server.js');
// const app = require('../../build/app.js'); <----- remove unused import

let supertest = require('supertest')(AppInstance.getExpressInstance());