Мокко / Sinon тест мангуста внутри экспресс

#node.js #mongoose #promise #mocha.js #sinon

#node.js #мангуст #обещаю #mocha.js #sinon

Вопрос:

Я пытаюсь протестировать этот экспресс-маршрут с помощью mocha, supertest и sinon. Тест не может передать обещание, он останавливается после первого вызова mongoose в User.найдите функцию обратного вызова с ожидающим сообщением об ошибке :

Ошибка: превышено время ожидания 2000 мс. Убедитесь, что в этом тесте вызывается обратный вызов done().

Я вызываю done() в обратном вызове, но ничего…

 module.exports = function(app, User) {
app.route('/appointments')
.post(function(req,res){

    User.find({'department': req.body.department}, function(err, workers){
        return workers._id;
    }).then(function(allWorkers){

        var deferred = Q.defer();

        function sortWorkers(worker){
            return Appointments.find({worker: worker._id, start: req.body.date});
        };

        Q.all(_.map(allWorkers, sortWorkers)).done(function (val) {
            deferred.resolve(val);
        });

        return deferred.promise;

    }).then(function(workers){
        console.log(workers);
    })
    .catch(function(error) {
        console.log(error);
    })
    .done();
})
};
  

Это мой тест begin :

 it("should save a user and not save the same", function(done){
    var appointments = new Appointments({title: 'okok',worker: '580359c86f7159e767db16a9',start:'2015-04-08T02:50:04.252Z' ,department: 95});

    console.log('appointments',appointments);
    request(app)
    .post("/appointments")
    .send(appointments)
    .expect(200)
    .end(function(err,res){
        console.log('ok',res);
        done();
    });
});
  

Ответ №1:

Во-первых, вам не нужно звонить done в User.find promise

Кроме того, вы app.route('/appointments').post никогда ничего не возвращаете в качестве ответа, попробуйте добавить

 res.end();
  

где у вас есть console.log .then и .catch ваше обещание. Вы также можете использовать код состояния HTTP, например

 ...
}).then(function(workers){
   res.status(200).end();
})
.catch(function(error) {
   res.status(500).end();
})
  

Это гарантирует, что .end(function(err,res){ ... }) в вашем тесте вызывается и вызывается правильная done функция.

Ответ №2:

Вы всегда должны возвращать обещание из вашего модульного теста. Все, что вам нужно, это добавить возврат перед запросом (приложение):

 return  request(app)
        .post("/appointments")
        . . .
        .then(() => {
           expect(<your actual value>).to.equal(<expected value>)
        })
  

Комментарии:

1. Да, я пробую это, но это не работает, я думаю, проблема в Q.all() во время блокировки тестового запроса на этом уровне. Как это проверить?

Ответ №3:

Я нашел решение: в моей функции some of .then нет условия и ничего не возвращает, если, например, рабочий массив пуст, поэтому время ожидания возврата моего теста превысило 2000 мс.

Я добавляю :

 User.find({'department': req.body.department}, function(err, workers){
        if(workers.length == 0){
            res.status(500).json({ message: "Nobody in this department" });
        }
        return workers;
    })...