如何在Jasmine单元测试中正确访问指令的范围和控制器

时间:2014-09-22 19:59:55

标签: angularjs unit-testing angularjs-scope jasmine

我的问题的要点是我不认为我在附带的单元测试中正确访问了我的指令的范围和控制器。

我的指令看起来像这样:

app.controller('GalleryDirectiveController', ['$scope', '$element', '$timeout', function($scope, $element, $timeout){
    $scope.panels = [];

    this.addPanel = function(panel){
        // Timeout to help with $scope.$watch in other directives
        return $timeout(function(){ $scope.panels.push(panel); }, 0);
    };
}]);

app.directive('gallery', function(){
    return {
        restrict: 'E',
        controller: 'GalleryDirectiveController'
    };
});

我现在要做的是编写单元测试,模拟将自己添加到库中的库面板集合。不幸的是,我认为我在单元测试中没有正确访问指令的控制器和范围,因此它们永远不会通过。

单元测试看起来像这样:

describe('app Gallery', function(){
    var gallery;
    var $scope;

    beforeEach(module('app'));

    beforeEach(inject(function($compile, $rootScope){

        var element = angular.element('<gallery/>');
        $compile(element)($rootScope.$new());
        $rootScope.$digest();

        $scope = element.isolateScope() || element.scope();
        gallery = element.controller('gallery');

    }));

    it('should add panels to the gallery', function(){
        for (var i = 0; i < 9; i++) {
            gallery.addPanel({
                $el : $('<div></div>')
            });
        }

        // Each panel is added in a timeout, so I thought
        // the problem might have been a timing issue
        waitsFor(function(){
            return $scope.panels.length !== 0;
        }, 'the panels to be added', 200);

    });
});

$ scope.panels.length始终为零。这让我觉得我在单元测试中设置的$ scope变量与控制器修改的$ scope不同。对于它的价值,检查gallery.addPanel和$ scope.panels是否定义的其他单元测试按预期传递。

希望我只是错过了一些小事。我担心的是,我可能已经创建了一个难以测试的画廊指令。

1 个答案:

答案 0 :(得分:1)

您可以在设定期望之前刷新$timeout

即: -

var $timeout; //or var flushTimeout;
...
beforeEach(inject(function($compile, $rootScope, _$timeout_){ //<-- inject timeout
        $timeout = _$timeout_; //Save it in outer scope
        //or flushTimeout = _$timeout_.flush


...

并在你的测试中做: -

it('should add panels to the gallery', function(){
    for (var i = 0; i < 9; i++) {
        gallery.addPanel({
            $el : $('<div></div>')
        });
    }
    $timeout.flush(); //or flushTimeout();
    expect($scope.panels.length).toEqual(9);
});

<强> Test Demo