TypeScript + Mocha + Express - TypeError: app.address is not a function
TypeScript + Mocha + Express - TypeError: app.address is not a function
在将 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。
您必须将 http.Server 或 Express 应用程序传递给 supertest
,您的 app
(const app = require('../../build/app.js');
) 只是一个包装 class。
你需要传递给supertest
的是appInstance.app
我的建议:
在你的 App 中创建 express 实例到 public:
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());
在将 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。
您必须将 http.Server 或 Express 应用程序传递给 supertest
,您的 app
(const app = require('../../build/app.js');
) 只是一个包装 class。
你需要传递给supertest
的是appInstance.app
我的建议:
在你的 App 中创建 express 实例到 public:
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());