UnhandledPromiseRejectionWarning in транспортир - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь получить значения из mongoDB, и это дает мне UnhandledPromiseRejectionWarning: MongoError: topology was destroyed

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().

[DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Ниже приведена уменьшенная версия кода

КЛАСС 1

connectToMongoDatabase() {
    try {
        return new Promise((resolve, reject) => {
            mongoclient.connect('mongodb://************************', (err, db) => {
                if (err) {
                    reject(err);
                }
                else {
                    resolve(db);
                }
            });
        });
    }
    catch (err) {
        console.log(err);
    }
}


fetchIssuesFromMongo(dbName, collectionName, query, db) {
    try {
        let dbo = db.db(dbName);
        return new Promise((resolve, reject) => {
            let collection = dbo.collection(collectionName);
            collection.find(query, (err, result) => {
                if (err) {
                    reject(err);
                }
                else {
                    resolve(result);
                    dbo.close();
                }
            });
        });
    }
    catch (err) {
        console.log(err);
    }
}

КЛАСС 2

executeQuery(issueCount){
   this.CLASS1.connectToMongoDatabase().then((db) => {
       this.CLASS1.fetchIssuesFromMongo(dbName, collectionName, query, db).then((result: any) => {
           expect(result.count()).toEqual(issueCount);
       });
  });
}

ФАЙЛ SPEC

it('verify result', (done) => {
    CLASS2.executeQuery(6).then(() => {
         done();
    });    
});

То, что я думаю, это тест не пройден после this.CLASS1.connectToMongoDatabase() Есть ли проблема с тем, как я использую обещания? Я выполняю все обещания, и у меня есть заявления об отклонении.

Есть предложения?

1 Ответ

0 голосов
/ 10 января 2019

Обновление вашего класса 1

Удалите попытку catch, поскольку она никогда не зацепит возвращенное обещание. Вот изменение для fetchIssuesFromMongo. Вы должны сделать что-то подобное для connectToMongoDatabase

fetchIssuesFromMongo(dbName, collectionName, query, db) {
  const dbo = db.db(dbName);
  return new Promise((resolve, reject) => {
    const collection = dbo.collection(collectionName);
    collection.find(query, (err, result) => {
      if (err) {
        reject(err); // at this point you should call a .catch
      } else {
        dbo.close();  // switching the order so the close actually happens.
                      // if you want this to close at the exit, you should
                      // probably not do it like this.
        resolve(result);
      }
    });
  });
}

Исправление executeQuery в классе 2

В вашем executQuery:

executeQuery(issueCount){
  // if connectToMongoDatabase is thenable, then you should also call .catch
  // you should also return a promise here so your Protractor code can actually
  // call .then in `CLASS2.executeQuery(6).then`
  return this.CLASS1.connectToMongoDatabase().then((db) => {
    this.CLASS1.fetchIssuesFromMongo(dbName, collectionName, query, db).then((result: any) => {
      expect(result.count()).toEqual(issueCount);
    }).catch(e => {
      console.log(e);
    });
  }).catch(e => {
    console.log(e);
  });
}

Подумайте об использовании async / await.

Это обычно помогает прояснить вложенную цепочку обещаний. Я предпочитаю это.

// this returns implicitly returns a Promise<void>
async executeQuery(issueCount) {
  // valid to use try catch
  try {
    const db = await this.CLASS1.connectToMongoDatabase();
    const result = await this.CLASS1.fetchIssuesFromMongo(dbName, collectionName, query, db);
    expect(result.count()).toEqual(issueCount);
  } catch(e) {
    console.log(e);
  }
}

Используйте async / await в тесте транспортира

Наконец, в тесте Protractor вы должны отключить менеджер обещаний селена. Это то, что вы будете делать в вашем файле конфигурации. SELENIUM_PROMISE_MANAGER: false,

Далее вы можете использовать async / wait в вашем тесте.

it('verify result', async () => {
    await CLASS2.executeQuery(6);
});

Я не фанат ожидания условия в вашем классе, и, возможно, было бы лучше вернуть значение из класса 2. Поэтому я мог бы возвратить Promise из executeQuery.

const issueCount = 6;
const queryResult = await CLASS2.executeQuery(issueCount);
expect(queryResult).toEqual(issueCount);

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...