TypeScript + Mocha + Express - TypeError: app.address не является функцией - PullRequest
0 голосов
/ 21 июня 2019

При преобразовании 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.

1 Ответ

1 голос
/ 21 июня 2019

Вы должны передать http.Server или приложение Express на supertest, ваш app (const app = require('../../build/app.js');) просто является классом переноса.

То, что вам нужно передать на supertest is 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 вы должны экспортироватьЭкземпляр приложения:

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...