【问题标题】:TypeScript + Mocha + Express - TypeError: app.address is not a functionTypeScript + Mocha + Express - TypeError: app.address 不是函数
【发布时间】:2019-11-03 19:08:22
【问题描述】:

在将 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);
        }
    }

}

然后每个控制器至少包含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。

【问题讨论】:

  • 您是否缺少导出功能?我在 server.ts 中没有看到导出
  • @sparrow server.ts 实际上只是一个便利的加载器,它使用要加载的控制器数组实例化应用程序,因为我必须先导入然后手动加载。

标签: javascript node.js typescript express mocha.js


【解决方案1】:

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

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

我的建议:

在您的应用程序中公开快速实例:

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());

【讨论】:

  • 非常感谢!我全都转过身来,想看看该怎么做。我的 REST API 测试现在又开始工作了 :)
猜你喜欢
  • 1970-01-01
  • 2021-04-19
  • 1970-01-01
  • 2018-10-04
  • 2018-05-22
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多