在将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。
答案 0 :(得分:1)
您必须将http.Server或Express应用传递给supertest
,您的app
(const 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());