AngularJS 有承诺的单元测试控制器
AngularJS Unit Test Controller with a promise
我在我的控制器中定义了以下代码
(function() {
'use strict';
angular
.module('bolt')
.controller('PackdownController', PackdownController);
PackdownController.$inject = ['$location', '$timeout', 'packdownService', 'modelTransformer', 'Packdown'];
function PackdownController($location, $timeout, packdownService, modelTransformer, Packdown) {
var vm = this;
vm.totalItemCount = 0;
vm.completedItemCount = 0;
vm.toDoItems = [];
vm.completedItems = [];
activatePackdown();
function activatePackdown() {
packdownService.GetAllTasks().then(function(data) {
if(data !== undefined && data !== null) {
if(data.error.state) {
showError('Error retrieving tasks', 'Please try again. If the problem persists, contact your supervisor', 'Close', toggleErrorModal);
}
else {
vm.totalItemCount = tasks.openItems + tasks.closeItems;
vm.completedItemCount = tasks.closeItems;
angular.forEach(tasks.bayTasks, function(value, key) {
if(value.status.description !== 'COMPLETED_THIS_CYCLE') {
var task = {
deptNbr: value.department.number,
bayName: value.aisle + '-' + value.bay,
status: {
code: value.status.code,
description: value.status.description
}
};
this.push(task);
}
}, vm.toDoItems);
angular.forEach(tasks.bayTasks, function(value, key) {
if(value.status.description === 'COMPLETED_THIS_CYCLE') {
var task = {
deptNbr: value.department.number,
bayName: value.aisle + '-' + value.bay,
completedBy: value.completedSystemUserId,
completedOn: new Date(value.completedTimeStamp)
};
this.push(task);
}
}, vm.completedItems);
}
}
});
}
}
})();
activatePackdown 是一个私有函数,所以我不能直接测试它,但我可以在创建控制器后测试 public 属性的值。但是,由于该函数调用服务方法(即 returns 承诺),我不知道如何在 .then 语句中进行测试。我的单元测试有以下内容:
describe('activatePackdown', function(){
it('should call GetAllTasks and then set completed/total counts', function(done) {
var spy = sinon.spy(this.packdownService, 'GetAllTasks');
var ctlr = $controller('PackdownController');
expect(spy).toHaveBeenCalled();
});
});
.toHaveBeenCalled 通过得很好,但我尝试做的一切都是为了测试 .then 中的属性状态。例如,vm.totalItemCount 的值。我知道我实际上并不希望 GetAllTasks 方法为 运行,因此我使用 sinon.spy 创建了间谍程序,但我现在不知道下一步该做什么。我尝试了在不同博客上找到的几种不同建议,但似乎没有任何效果。非常感谢任何帮助
使用茉莉花,
我会模拟注入 $q 和 $controller;
var deferred = $q.defer();
spyOn(Object, 'method').and.returnValue(deferred.promise);
controller.method(); //Calling your controller method
然后测试你的成功
$scope.$apply(function () {
deferred.resolve(<insert expected object>);
});
出现错误时测试你的then
$scope.$apply(function () {
deferred.reject();
});
仅供将来参考,这是我的工作测试现在的样子
it('should call GetAllTasks and then set completed/total counts', function() {
var deferred = this.$q.defer();
var stub = sinon.stub(this.packdownService, 'GetAllTasks').returns(deferred.promise);
deferred.resolve(response);
var ctlr = $controller('PackdownController');
this.$timeout.flush();
expect(ctlr.totalItemCount).toEqual(4);
this.$timeout.verifyNoPendingTasks();
});
我在我的控制器中定义了以下代码
(function() {
'use strict';
angular
.module('bolt')
.controller('PackdownController', PackdownController);
PackdownController.$inject = ['$location', '$timeout', 'packdownService', 'modelTransformer', 'Packdown'];
function PackdownController($location, $timeout, packdownService, modelTransformer, Packdown) {
var vm = this;
vm.totalItemCount = 0;
vm.completedItemCount = 0;
vm.toDoItems = [];
vm.completedItems = [];
activatePackdown();
function activatePackdown() {
packdownService.GetAllTasks().then(function(data) {
if(data !== undefined && data !== null) {
if(data.error.state) {
showError('Error retrieving tasks', 'Please try again. If the problem persists, contact your supervisor', 'Close', toggleErrorModal);
}
else {
vm.totalItemCount = tasks.openItems + tasks.closeItems;
vm.completedItemCount = tasks.closeItems;
angular.forEach(tasks.bayTasks, function(value, key) {
if(value.status.description !== 'COMPLETED_THIS_CYCLE') {
var task = {
deptNbr: value.department.number,
bayName: value.aisle + '-' + value.bay,
status: {
code: value.status.code,
description: value.status.description
}
};
this.push(task);
}
}, vm.toDoItems);
angular.forEach(tasks.bayTasks, function(value, key) {
if(value.status.description === 'COMPLETED_THIS_CYCLE') {
var task = {
deptNbr: value.department.number,
bayName: value.aisle + '-' + value.bay,
completedBy: value.completedSystemUserId,
completedOn: new Date(value.completedTimeStamp)
};
this.push(task);
}
}, vm.completedItems);
}
}
});
}
}
})();
activatePackdown 是一个私有函数,所以我不能直接测试它,但我可以在创建控制器后测试 public 属性的值。但是,由于该函数调用服务方法(即 returns 承诺),我不知道如何在 .then 语句中进行测试。我的单元测试有以下内容:
describe('activatePackdown', function(){
it('should call GetAllTasks and then set completed/total counts', function(done) {
var spy = sinon.spy(this.packdownService, 'GetAllTasks');
var ctlr = $controller('PackdownController');
expect(spy).toHaveBeenCalled();
});
});
.toHaveBeenCalled 通过得很好,但我尝试做的一切都是为了测试 .then 中的属性状态。例如,vm.totalItemCount 的值。我知道我实际上并不希望 GetAllTasks 方法为 运行,因此我使用 sinon.spy 创建了间谍程序,但我现在不知道下一步该做什么。我尝试了在不同博客上找到的几种不同建议,但似乎没有任何效果。非常感谢任何帮助
使用茉莉花, 我会模拟注入 $q 和 $controller;
var deferred = $q.defer();
spyOn(Object, 'method').and.returnValue(deferred.promise);
controller.method(); //Calling your controller method
然后测试你的成功
$scope.$apply(function () {
deferred.resolve(<insert expected object>);
});
出现错误时测试你的then
$scope.$apply(function () {
deferred.reject();
});
仅供将来参考,这是我的工作测试现在的样子
it('should call GetAllTasks and then set completed/total counts', function() {
var deferred = this.$q.defer();
var stub = sinon.stub(this.packdownService, 'GetAllTasks').returns(deferred.promise);
deferred.resolve(response);
var ctlr = $controller('PackdownController');
this.$timeout.flush();
expect(ctlr.totalItemCount).toEqual(4);
this.$timeout.verifyNoPendingTasks();
});