Как ждать или обмениваться данными между файлами в mocha

#javascript #node.js #mocha.js #chai

#javascript #node.js #mocha.js #чай

Вопрос:

Итак, допустим, у меня есть файл с именем «main.js «. Он содержит это:

 const User = require('../models/user');

describe('Testing', () => {
    before(async function(){
        await User.deleteMany({});
    });
    require('./users/createUser');
    require('./users/activateUser');
});
 

Как вы можете видеть, перед всеми тестами я очищаю коллекцию «пользователи».
Затем мне требуется 2 файла. Их содержимое следующее:

     //createUser.js

    let activationCode = undefined;

    describe('Create User', () => {
        it('it should POST a user when post data is valid', (done) => {
            chai.request(server)
                .post('/user/post')
                .send(userJson)
                .end((err, res) => {
                    res.should.have.status(200);
                    res.body.should.be.a('object');
                    res.body.should.have.property('message').eql('USER_ADDED');
                    activationCode = res.body.user.activationString;
                    done();
                });
        });

    });

    //activateUser.js

    //Here, Im in stuck because I dont have access to the variable activationCode created in createUser.js
 

Как вы можете видеть, во втором требуемом файле я хотел бы получить доступ к activationString, созданной в первом требуемом файле.
Но кажется, что требуемые файлы выполняются параллельно, что делает невозможным доступ к переменной из другого файла.

Что я могу сделать? createUser.js может быть, должен быть асинхронный som в main.js Я жду, пока он будет завершен, прежде чем запрашивать второй файл?

Ответ №1:

Mocha по умолчанию запускает набор тестов в последовательном режиме, независимо от того, является ли тестируемый код синхронным или асинхронным. Поэтому набор тестов будет выполняться в том порядке, в котором файлы загружаются require .

Вы могли бы проявить смекалку и попытаться обойти это ограничение, назначив что-то глобальному объекту, но это не будет работать в параллельном режиме. Вероятно, лучше играть по правилам!

Это означает, что вы можете объявить activationCode переменную как свойство global объекта и получить к ней доступ через тестовые файлы в одном процессе (последовательный режим). Разным процессам выделяется разная память, поэтому доступ к глобальным объектам между процессами невозможен. это означает, что этот способ НЕ будет работать в параллельном режиме

Вот пример, показывающий, как получить доступ activationCode к переменной через global объект.

createUser.js :

 global.activationCode = undefined;

describe('Create User', () => {
  it('should create user and get the activation code', (done) => {
    // simulate asynchronous operation
    setTimeout(() => {
      global.activationCode = 'success';
      console.log(new Date().toISOString());
      done();
    }, 3000);
  });
});
 

activateUser.js :

 const { expect } = require('chai');

describe('Activate User', () => {
  it('should activate user', (done) => {
    setTimeout(() => {
      expect(global.activationCode).to.be.eql('success');
      console.log(new Date().toISOString());
      done();
    }, 1000);
  });
});
 

index.test.js :

 describe('Testing', () => {
  before(function(done) {
    setTimeout(() => {
      console.log('delete user');
      console.log(new Date().toISOString());
      done();
    }, 1000);
  });
  require('./createUser');
  require('./activateUser');
});
 

результат теста:

   Testing
delete user
2020-12-23T12:10:00.585Z
    Create User
2020-12-23T12:10:03.587Z
      ✓ should create user and get the activation code (3000ms)
    Activate User
2020-12-23T12:10:04.590Z
      ✓ should activate user (1002ms)


  2 passing (5s)