如何在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变量与控制器修改的$scop变量不同。值得一提的是,其他检查gallery.addPanel和$scope.panels是否定义为预期通过的单元测试。

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

您可以在设置期望值之前刷新$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);
});

测试演示

最新更新