UnhandledPromiseRejection警告。使用npm run test运行时的警告

时间:2018-08-02 03:07:44

标签: javascript node.js mongodb mongoose mocha

我是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运行,则会收到这些警告。

发生了什么事?

1 个答案:

答案 0 :(得分:1)

您的错误提示Cannot read property 'name' of null

这意味着您试图访问应该指向对象但实际上为name的变量上的名为null的属性。

您的代码中访问name的唯一位置是:

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

这意味着,在运行此代码时,您的数据库中没有带有name: 'Mario'的文档。

发生这种情况的原因是因为您的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
});

您还应该能够使用异步功能以提高可读性:

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');
  });
});

或(使用异步功能):

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