Я новичок в 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
, я получаю эти предупреждения.
Что происходит?
В вашей ошибке сказано 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');
});
done
никогда не вызывается при сбое подтверждения. Надлежащим способом сделать это сMarioChar.findOne(...).then(...).then(done, done)
являетсяMarioChar.findOne(...).then(...).then(done, done)
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(); }); });
Помогите плз!