我是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
运行,则会收到这些警告。
发生了什么事?
答案 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');
});