如何对Angular控制器改变路线进行单元测试

时间:2014-07-16 22:01:29

标签: angularjs unit-testing jasmine karma-runner

我试图弄清楚如何测试我的控制器逻辑来处理更改路由,但即使代码在浏览器中工作,当测试运行代码时,它似乎并没有改变路线。

这是我的控制器的简化版本

myApp.controller('locationController', ['$location',
    function($location) {
        'use strict';
        $location.path('/dashboard');
    }
]);

最简单的测试,只是检查控制器是否已加载,路由是否从最初设置的位置变为其他位置

describe('Testing c-app-controller logic', function() {
    var ctrl,
        $scope,
        $rootScope,
        location,
        route;

    beforeEach(function() {
        module('optApp');
        inject(function (_$rootScope_, $controller, _api_, _$location_, $httpBackend, $route) {
            $scope = $rootScope.$new();
            $rootScope = _$rootScope_;
            location = _$location_;
            route = $route;
            ctrl = $controller('locationController', {
                $scope: $scope,
                $rootScope: _$rootScope_,
                location: _$location_,
                route: $route
            });
        });
    });

    describe('location controller', function () {
        it('should change location', function () {
            location.path('/login');
            expect(route.current.controller).toBe('locationController');
            $rootScope.$digest();
            expect(location.path()).toBe('/dashboard');
        });
    });

});

这是我得到的:

Expected '/login' to be '/dashboard'.
Error: Expected '/login' to be '/dashboard'.

1 个答案:

答案 0 :(得分:0)

嗯,奇怪的是,我似乎已经找到了让它发挥作用的方法。关于Angular摘要如何在测试中运行的一些奇怪的东西,但是如果我将代码包装在函数中并从测试中调用函数,我可以获得改变的路径和测试成功。

控制器

myApp.controller('locationController', ['$location',
    function($location) {
        'use strict';
        $scope.changeLocation = function(){
            $location.path('/dashboard');
        }
    }
]);

测试

describe('Testing c-app-controller logic', function() {
    var ctrl,
        $scope,
        $rootScope,
        location,
        route;

    beforeEach(function() {
        module('optApp');
        inject(function (_$rootScope_, $controller, _api_, _$location_, $httpBackend, $route) {
            $scope = $rootScope.$new();
            $rootScope = _$rootScope_;
            location = _$location_;
            route = $route;
            ctrl = $controller('locationController', {
                $scope: $scope,
                $rootScope: _$rootScope_,
                location: _$location_,
                route: $route
            });
        });
    });

    describe('location controller', function () {
        it('should change location', function () {
            location.path('/login');
            expect(route.current.controller).toBe('locationController');
            $scope.changeLocation();
            $rootScope.$digest();
            expect(location.path()).toBe('/dashboard');
        });
    });

});