UnhandledPromiseRejectionWarning. Предупреждения при запуске с использованием npm run test

1

Я новичок в MongoDB и я использую библиотеку mongoose чтобы помочь мне хранить данные в MongoDB. Хотя все мои (mocha) тесты проходят, я все равно продолжаю получать эту ошибку:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'name' of null
  at C:\MY STUFF\CODING\Projects\mongodb tutorial\mongodb-playlist\test\finding_test.js:33:21
  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()
  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.

Вот мой код:

const assert = require('assert');
const MarioChar = require('../models/mariochar');


describe('Finding records', function(){
  // this.timeout(15000);
  var char;

  beforeEach(function(done){
    char = new MarioChar({
      name: 'Mario'
    });

    // now test it
    char.save().then(function(){
      // done(); 
    });
    done();
  });

  it('Finds one record from the database', function(done){
    // this.timeout(15000);
    MarioChar.findOne({name: 'Mario'}).then(function(result){
      assert(result.name === 'Mario');
      // done();
    });
    done();
  });

  it('Finds one record by ID from the database', function(done){

    MarioChar.findOne({_id: char._id}).then(function(result){
      assert(result._id.toString() === char._id.toString());
      // done();
    });
    done();
  });
});

Комментарии - это то, что я попробовал, чтобы удалить эти ошибки/предупреждения.

Когда я запускаю с помощью mocha --trace-warnings finding_test.js я не получаю никаких предупреждений, однако, если я запускаю с помощью этой команды npm run test, я получаю эти предупреждения.

Что происходит?

Теги:
mocha
mongoose

1 ответ

1

В вашей ошибке сказано Cannot read property 'name' of null.

Это означает, что вы пытаетесь получить доступ к name под name переменной, которая должна указывать на объект, но на самом деле является null.

Единственное место в коде, где вы обращаетесь name является:

MarioChar.findOne({name: 'Mario'}).then(function(result){
  assert(result.name === 'Mario'); // <---- here
});

Это означает, что в момент запуска этого кода нет документа с name: 'Mario' в вашем db.

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

Вы вызываете done до создания:

beforeEach(function(done){
  char = new MarioChar({
    name: 'Mario'
  });

  char.save().then(function(){
    // this part is called when the document is created
  });
  done(); // this executes before document is created
});

Вы должны вызвать его после сохранения (а также при ошибке):

beforeEach(function(done){
  char = new MarioChar({
    name: 'Mario'
  });

  char.save()
   .then(done)   // we are done when successful
   .catch(done); // and when erroring
});

Вы также должны иметь возможность использовать функцию async для лучшей читаемости:

beforeEach(async function() {
  char = await new MarioChar({
    name: 'Mario'
  }).save();
});

Примечание: У вас есть несколько других мест, где вы не призвание done должным образом, как и в тестах (на it вызовах). Вы должны вызвать done в этих обратных вызовов, а также или вернуть обещания.

Например, это:

it('Finds one record from the database', function(done){
  MarioChar.findOne({name: 'Mario'}).then(function(result){
    assert(result.name === 'Mario');
  });
  done();
});

Должен быть либо:

it('Finds one record from the database', function(done){
  MarioChar.findOne({name: 'Mario'}).then(function(result){
    assert(result.name === 'Mario');
    done(); // call done here
  })
  .catch(done); // and here
});

Или (верните обещание):

it('Finds one record from the database', function(){
  return MarioChar.findOne({name: 'Mario'}).then(function(result){
    assert(result.name === 'Mario');
  });
});

Или (с помощью функции async):

it('Finds one record from the database', async function(){
  const result = await MarioChar.findOne({name: 'Mario'});
   assert(result.name === 'Mario');
});
  • 0
    Должен быть - не должен. Мокко, естественно, поддерживает обещания, используя готовые результаты в стандартном коде, который подвержен человеческим ошибкам, я вижу это все время. Это приведет к тайм-ауту теста и необработанному отклонению. done никогда не вызывается при сбое подтверждения. Надлежащим способом сделать это с MarioChar.findOne(...).then(...).then(done, done) является MarioChar.findOne(...).then(...).then(done, done)
  • 0
    Спасибо всем большое за вашу помощь. Мне удалось исправить это finding_test.js . Тем не менее, у меня есть другой код updating_test.js . Это похоже на приведенный выше код, просто для it блока я получаю эту ошибку UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value: assert(result.name === 'Luigi') для MarioChar.findOneAndUpdate({name: 'Mario'}, {name: 'Luigi'}).then(function(){ MarioChar.findOne({_id:char._id}).then(function(result){ assert(result.name === 'Luigi'); done(); }); }); Помогите плз!
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню