如何模拟指令 $scope 变量?

How to mock directive $scope variable?

我有一个如下所示的指令:

angular.module('myApp', [])
    .directive('myDirective', ['$window', function($window){
    return {
        link: function(scope, element, attr, controller) {

            var w = angular.element($window);
            function adjustTop(){
                var oldtop = scope.top;
                if(oldtop<15){
                    scope.top += 2;
                }else{
                    scope.top = 0;
                }
            }

            w.bind('scroll', function () {
                adjustTop();
            });

        }
    };
}]);

如何在单元测试中模拟 scope.top 值?

您可以简单地使用 $compile 来编译该指令,并将其与您分配给 top 属性的范围一起传递。要使用 scroll 事件测试 scope.top 的更改,您可以使用 JQLite 的 triggerHandler() 功能。

DEMO

单元测试

describe('myDirective', function() {

  var element, scope;

  beforeEach(module('myApp'));

  beforeEach(inject(function($compile, $rootScope) {
    scope = $rootScope.$new();
    scope.top = 10;
    element = $compile('<div my-directive></div>')(scope);
  }));

  it('should change the scope value when scrolling', inject(function($window) {
    var jqWindow = angular.element($window);
    jqWindow.triggerHandler('scroll');
    expect(scope.top).toBe(12);
    jqWindow.triggerHandler('scroll');
    expect(scope.top).toBe(14);
    jqWindow.triggerHandler('scroll');
    expect(scope.top).toBe(16);
    jqWindow.triggerHandler('scroll');
    expect(scope.top).toBe(0);
  }));

});

注意:在您的绑定事件中添加一个 scope.$apply() 以通知 angular 您已经在 angular 的上下文中进行了更改,例如范围值。

w.bind('scroll', function () {
  adjustTop();
  scope.$apply();
});