处理Angular测试中的众多依赖项和$ http期望

时间:2015-09-18 19:41:50

标签: angularjs

我有以下Angular控制器:

     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;
        });
    });
   ...

它有许多依赖项。

我只是想测试一下这个控制器确实在currentUserAccount上设置了$scope

我有以下Angular测试 - 工作正常:

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依赖domainService模块中的utils依赖项,$http模块本身会进行多次{{1}}次调用。

这迫使我必须在我的测试中设置许多期望,导致笨拙的测试代码......

有人可以建议解决这个问题吗?我错过了什么?这是测试设计问题还是应用程序设计问题?

1 个答案:

答案 0 :(得分:0)

用户JB Nizet建议我重新安排我的依赖项,从而使我走上正轨。

使用这个漂亮的工具http://angularjs-graph.org/github,我能够可视化我的角度依赖图并重新排列依赖关系,从而避免在我的测试中加载所有依赖项。

我的测试现在更加简洁,我避免了不必要的期望:

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(我的应用名称)模块,然后我选择性地使用所需的模块。

相关问题