Angularjs 在角度测试中处理大量依赖项和$http期望
我有以下角度控制器:Angularjs 在角度测试中处理大量依赖项和$http期望,angularjs,Angularjs,我有以下角度控制器: angular.module('dashboard') .controller('DashboardCtrl', ['$rootScope', '$scope', '$interval', 'domainService', 'messageService', 'currentUserAccount', 'unreadMessagesCount', 'latestMessages', function ($rootScope, $scope, $in
angular.module('dashboard')
.controller('DashboardCtrl', ['$rootScope', '$scope', '$interval', 'domainService', 'messageService', 'currentUserAccount', 'unreadMessagesCount', 'latestMessages', function ($rootScope, $scope, $interval, domainService, messageService, currentUserAccount, unreadMessagesCount, latestMessages) {
$scope.$on('useraccount:updated', function () {
domainService.currentUserAccount().success(function (data) {
$scope.currentUserAccount = data;
});
});
...
它有许多依赖项
我只是想测试这个控制器是否在$scope
上设置了currentUserAccount
我有以下角度测试-效果很好:
describe('DashboardCtrl', function () {
var scope, httpBackend;
beforeEach(module('bignibou', 'dashboard'));
beforeEach(inject(function ($controller, $rootScope, domainService, messageService, $httpBackend) {
scope = $rootScope.$new();
$controller('DashboardCtrl', {
$scope: scope,
domainService: domainService,
messageService: messageService,
currentUserAccount: {data: {firstName: 'John'}},
unreadMessagesCount: 0,
latestMessages: []
});
httpBackend = $httpBackend;
//TODO: do I need all those expectations?
httpBackend.whenGET('/api/utils/signup-roles').respond({});
httpBackend.whenGET('/api/utils/parents-needs').respond({});
httpBackend.whenGET('/api/utils/childcare-worker-types').respond({});
httpBackend.whenGET('/api/utils/childcare-types').respond({});
httpBackend.whenGET('/api/utils/all-day-to-time-slots').respond({});
httpBackend.whenGET('/api/utils/regular-day-to-time-slots').respond({});
httpBackend.whenGET('/info').respond({build: {version: '1.0'}});
httpBackend.whenGET(/app.+/).respond({});
httpBackend.whenGET('/api/utils/current-useraccount').respond({id: 42, firstName: 'Pedro'});
}));
it('should handle user account updated', function () {
scope.$emit('useraccount:updated');
httpBackend.flush();
expect(scope.currentUserAccount.firstName).toEqual('Pedro');
});
});
然而,我对它并不满意,因为它有许多依赖关系——更糟糕的是,未完成的期望/请求变得越来越难处理
原因是我依赖于上面作为bignibou
导入的顶级模块
以下是本模块的声明:
angular.module('bignibou', [
'ngResource', 'ngMessages', 'ngCookies', 'ngAnimate', 'ngTouch', 'ngSanitize',
'ui.router', 'ui.utils', 'ui.bootstrap', 'pascalprecht.translate', 'angularMoment', 'checklist-model', 'ngTagsInput', 'angular-loading-bar', 'cfp.loadingBar',
'home', 'signup', 'signin', 'signout', 'navbar', 'dashboard', 'useraccount', 'advertisement', 'search', 'geolocation', 'utils', 'message'
]);
angular.module('home', []);
angular.module('signup', []);
angular.module('signin', []);
angular.module('signout', []);
angular.module('navbar', []);
angular.module('dashboard', []);
angular.module('useraccount', []);
angular.module('advertisement', []);
angular.module('search', []);
angular.module('geolocation', []);
angular.module('message', []);
angular.module('utils', []);
然后在utils
模块中,我有许多$http
调用:
.run(['$rootScope', 'domainService', function ($rootScope, domainService) {
domainService.signupRoles().then(function (param) {
$rootScope.signupRoles = param.data;
});
domainService.parentsNeeds().then(function (param) {
$rootScope.parentsNeeds = param.data;
});
domainService.childcareWorkerTypes().then(function (param) {
$rootScope.childcareWorkerTypes = param.data;
});
domainService.childcareTypes().then(function (param) {
$rootScope.childcareTypes = param.data;
});
domainService.allDayToTimeSlots().then(function (param) {
$rootScope.allDayToTimeSlots = param.data;
});
domainService.regularDayToTimeSlots().then(function (param) {
$rootScope.regularDayToTimeSlots = param.data;
});
}])
现在,我如何重新设计/重构我的测试,以避免所有的$http
调用
换句话说,我正在测试DashboardCtrl
,它依赖于utils
模块中的domainService
依赖项,该模块本身执行许多$http
调用
这迫使我不得不在测试中设置大量的期望值,导致测试代码笨拙
有人能提出解决这个问题的建议吗?我错过了什么?这是一个测试设计问题还是一个应用程序设计问题?用户建议我重新安排依赖项,这并没有让我走上正轨 使用这个很好的工具或工具,我能够可视化我的角度依赖关系图并重新排列依赖关系,从而避免在测试中加载所有依赖关系 现在,我的测试更加简洁,避免了不必要的期望:
describe('DashboardCtrl', function () {
var $scope, $httpBackend;
beforeEach(module('dashboard', 'utils', 'message'));
beforeEach(inject(function ($controller, $rootScope, domainService, messageService, _$httpBackend_) {
$scope = $rootScope.$new();
$controller('DashboardCtrl', {
$scope: $scope,
domainService: domainService,
messageService: messageService,
currentUserAccount: {data: {firstName: 'John'}},
unreadMessagesCount: 0,
latestMessages: []
});
$httpBackend = _$httpBackend_;
$httpBackend.whenGET('/api/utils/current-useraccount').respond({id: 42, firstName: 'Pedro'});
}));
it('should handle user account updated', function () {
$scope.$emit('useraccount:updated');
$httpBackend.flush();
expect($scope.currentUserAccount.firstName).toEqual('Pedro');
});
});
你可以看到,我不再拉顶级的
bignibou
(我的应用程序的名称)模块,然后我有选择地使用所需的模块。将这个run()块放在测试中不加载的模块中。我认为在我的测试中始终包含顶级模块(拉所有依赖项的模块)是最容易的在我的例子中,“bignibou”,但这似乎不是一个好主意。我猜这个问题迫使我更好地解释我的应用程序的依赖关系图。你推荐任何可以帮助我可视化依赖关系图的工具吗?这里有一个很好的工具可以帮助可视化某个应用程序的依赖关系图: