测试使用$ location服务的breadcrumb指令

时间:2014-12-04 19:11:49

标签: angularjs angularjs-directive jasmine karma-jasmine

我正在尝试为breadcrumb指令/服务编写一个简单的单元测试。基本上,我想要做的就是更改location.path(或者正确的方法),然后能够在指令的HTML上运行expect,看看面包屑列表是否已更新。

面包屑服务(从AngularJS Breadcrumbs Service借来)看起来像这样:

var commonModule = angular.module('app.common');

commonModule.factory('common.service.breadcrumbs', ['$rootScope', '$location', function($rootScope, $location){

    var breadcrumbs = [];
    var breadcrumbsService = {};

    function setBreadcrumbs() {
        var pathElements = $location.path().split('/'), result = [], i;
        var breadcrumbPath = function (index) {
            return '/' + (pathElements.slice(0, index + 1)).join('/');
        };

        pathElements.shift();
        for (i=0; i<pathElements.length; i++) {
            result.push({name: pathElements[i], path: breadcrumbPath(i)});
        }

        breadcrumbs = result;
    }

    setBreadcrumbs();

    // We want to update breadcrumbs only when a route is actually changed
    // $location.path() will get updated immediately (even if route change fails!)
    $rootScope.$on('$routeChangeSuccess', function(event, current){
        setBreadcrumbs();
    });

    breadcrumbsService.getAll = function() {
        return breadcrumbs;
    };

    breadcrumbsService.getFirst = function() {
        return breadcrumbs[0] || {};
    };

    return breadcrumbsService;
}]);

我目前的测试看起来像这样:

describe("Directive:", function() {

    beforeEach(angular.mock.module("app"));

    var $compile,
        $scope,
        $location;

    // Angular strips the underscores when injecting
    beforeEach(inject(function(_$compile_, _$rootScope_, _$location_) {
        $compile = _$compile_;
        $scope = _$rootScope_.$new();
        $location = _$location_;
    }));

    describe("breadcrumbs", function () {

        it("correctly display the path as breadcrumbs.",
            inject(['common.service.breadcrumbs', function(breadcrumbs) {

                //console.log($location.path());
                //$scope.$apply();
                $location.path('/analyze/reports');
                $scope.$apply();
                //console.log($location.path());
                //console.log(breadcrumbs.getAll());

                $scope.$broadcast('$routeChangeSuccess', {});

                // Build the directive
                var element = $compile('<div class="cf-breadcrumbs" cf-breadcrumbs></div>')($scope);
                $scope.$apply();

                console.log(element.html());
            }]));

    });

});

目前,我没有看到breadcrumb服务更新了面包屑数组。我已经尝试过console.log(breadcrumbs.getAll()),它总是返回没有两个新路径元素的相同数组。我担心它可能与时间相关,但不确定在我进行检查/应用之前我会等待$ routeChangeSuccess事件影响服务。

长话短说,我如何测试看到面包屑是否适当更新?

1 个答案:

答案 0 :(得分:1)

在你的测试中从$ rootScope广播$ p。 $ scope是$ rootScope的子范围,因为它是使用$rootScope.$new()创建的,所以从中广播的事件不会在你附加$ on处理程序的地方上升。

$ broadcasts向下旅行到儿童范围,而$则向上旅行。