У меня есть приложение MEAN, и я пытаюсь получить тесты для работы на стороне узла. Асинхронные события завершаются обещаниями, которые потребляются в контроллере. Я потерпел неудачу в тестировании контроллер :(Тестирование функции, которая потребляет обещания
Контроллер Я пытаюсь тест:
ProjectController.prototype.getAll = function(req, res, next) {
req.dic.subjectRepository
.getById(req.params.subjectId)
.then(function(subject) {
res.json(subject.projects);
}, function(err) {
return res.status(404).send('Subject does not exist.' + err);
});
};
subjectRepository
наш источник данных, который возвращает обещание (mpromise
, потому что под капотом мы используем mongoose
, но это не имеет значения):
Таким образом, в нашем тесте мы попытались насмешливым запрос (мы инъекционный нашей зависимость инъекционного контейнер из промежуточного слоя в req
) и ответ (тест завершается успешно, если response.json()
был назван с предметы, которые мы пытались извлечь) и наш предметRepository. Мы использовали bluebird
(хотя я пытался другие из разочарования), чтобы создать фальшивые обещания для наших издевались subjectRepository
:
describe('SubjectController', function() {
'use strict';
var Promise = require('bluebird');
it('gets all existing subjects', function() {
// -------------------------------------
// subjectRepository Mock
var subjectRepository = {
getAll: function() {},
};
var subjectPromise = Promise.resolve([
{name: 'test'},
{name: 'test2'},
]);
spyOn(subjectRepository, 'getAll').andReturn(subjectPromise);
// -------------------------------------
// request mock
var req = {
dic: {
subjectRepository: subjectRepository,
},
};
// -------------------------------------
// response mock
var res = {
json: function() {},
send: function() {},
};
spyOn(res, 'json');
// -------------------------------------
// actual test
var subjectController = new (require('../../../private/controllers/SubjectController'))();
subjectController.getAll(req, res);
// this succeeds
expect(subjectRepository.getAll).toHaveBeenCalled();
// this fails
// expect(res.json).toHaveBeenCalled();
});
});
Вопрос: Как мне сделать пробный запуск expect()
ПОСЛЕ обещанию удалось?
Узел v0.12
код на GitHub для тех, кто заинтересован: https://github.com/mihaeu/fair-projects
А может быть, я должен отметить, что контроллер называется от маршрутизатора:
// router handles only routing
// and controller handles data between view and model (=MVC)
subjectRouter.get('/:subjectId', subjectController.get);
I заставил это работать, изменив наши контроллеры, чтобы передать обещания, но я не уверен, что это то, что мы хотим. Разве нет способа заставить мой подход к работе?
it('gets all existing subjects', function(done) {
// ...
var subjectController = new (require('../../../private/controllers/SubjectController'))();
subjectController.getAll(req, res).then(function() {
expect(res.json).toHaveBeenCalledWith(testSubjects); // success
}).finally(done);
expect(subjectRepository.getAll).toHaveBeenCalled(); // success
}
Очень сложно, так как ваш метод getAll не возвращает обещание. Если это так (как в вашем обновлении), это должно быть легко. – Bergi