Заставить Mocha дождаться окончания загрузки index.js перед запуском тестовых файлов - PullRequest
1 голос
/ 20 июня 2019

У меня есть структура папок:

- app
  - config
    - config.js // environment variables
    - express.js // creates an express server
  - passwords
    - passwords.controller.js
    - passwords.route.js
    - passwords.test.js
  - index.js // main app file

Мой индексный файл загружает приложение асинхронно:

function initMongoose() {

  ...

  return mongoose.connect(config.mongo.host, {useNewUrlParser: true, keepAlive: 1})
    .then((connection) => {

      // Password is a function which connects the Password schema to the given connection
      Password(connection);
    })
    .catch((e) => {
      throw new Error(`Unable to connect to database: ${config.mongo.host}`);
    });
}

async init() {

  await initMongoose();

  const app = require('./config/express');
  const routes = require('./index.route');

  app.use('/api', routes);

  ...

  app.listen(3000, () => {
    console.log('server started');
  });
}

module.exports = init();

Мои тестовые файлы создаются следующим образом:

// Load the app async first then continue with the tests
require('../index').then((app) => {

  after((done) => {
    mongoose.models = {};
    mongoose.modelSchemas = {};
    mongoose.connection.close();
    done();
  });

  describe('## Passwords API', () => {
    ...
  });
});

Я начинаю тесты так:

"test": "cross-env NODE_ENV=test ./node_modules/.bin/mocha --ui bdd --reporter spec --colors server --recursive --full-trace"

Вот где странность одолевает меня.В основном он загружает passwords.controller.js до что-нибудь иначе, это из-за опции --recursive.Этого не должно происходить, поскольку index.js необходимо сначала загрузить, чтобы он мог подключиться к mongoose и т. Д. До начала любого из тестов, если этого не произойдет, этот фрагмент из passwords.controller.js выдаст MissingSchemaError: Schema hasn't been registered for model "Password"., поскольку модель Password убежищеНа этом этапе не было настроено:

const Password = mongoose.connection.model('Password');

Поэтому я попытался добавить --require ./index.js перед параметром --recursive, он действительно загружает другие файлы до passwords.controller.js, но последний все еще работает до того, как index.jsдаже закончил.

Решения здесь не работает, потому что index.js не запускается первым.

Как я могу изменить мой test скрипт, чтобы мойindex.js закончить, прежде чем запускать какие-либо тестовые файлы?

Ответы [ 2 ]

1 голос
/ 27 июня 2019
describe('## Passwords API', function() {
  let appInstance;

   before((done) => {
      require('index.js').then((app) => {
          appInstance = app
          done();
      });
   });
});

Ссылка: https://mochajs.org/#asynchronous-hooks

Другим возможным шаблоном является наличие специального вспомогательного файла. Это действует как синглтон или какой-то кеш. Это позволяет серверу быть загруженным только один раз, и он является общим для всего теста. Обратите внимание, что это может вызвать нежелательные побочные эффекты в ваших модульных тестах, но может ускорить тесты, которые не влияют на объект приложения.

Например testUtil.js

let app = null;
async function getApp(){
   if(app){
      return app;
   }
   app = await require('index.js')
   return app
}

module.export = {
   getApp,
}

и в вашем тестовом файле

const helper = require('[your path]/testUtil.js')
describe('## Passwords API', function() {
  let appInstance;

   before((done) => {
      helper.getApp().then((app) => {
          appInstance = app
          done();
      });
   });
});

Я бы также предложил поместить все тесты в отдельную папку (называемую, может быть, «тестами»). Это обеспечит загрузку только тестов --recursive. Еще одно преимущество: в производстве вы можете пропустить эту папку

0 голосов
/ 25 июня 2019

Технически вы можете запустить файл index.js и вместо использования mocha с помощью теста npm (CLI) вы можете запустить тест с mocha программно после index.js. Мокко Программный пример

import Mocha from 'mocha'; 
import fs from 'fs';
import path from 'path';

// Instantiate a Mocha instance.
const mocha = new Mocha();

const testDir = 'some/dir/test'

// Add each .js file to the mocha instance
fs.readdirSync(testDir).filter(function(file) {
    // Only keep the .js files
    return file.substr(-3) === '.js';

}).forEach(function(file) {
    mocha.addFile(
        path.join(testDir, file)
    );
});

// Run the tests.
mocha.run(function(failures) {
  process.exitCode = failures ? 1 : 0;  // exit with non-zero status if there were failures
});
...