AngularJS - 使用Windows滚动进行单元测试

时间:2015-04-04 13:25:51

标签: angularjs unit-testing jasmine karma-jasmine

我的指令看起来像这样:

angular.directive('myDirective', ['$window', function($window){
    return function (scope, element) {
        var w = angular.element($window);
        var top = element.offset().top-w.scrollTop();

        function adjustTop(){
            var oldtop = scope.top;
            var scrolltop = w.scrollTop();
            var winHeight = w.height();
            console.log("scrolltop:"+scrolltop);
            console.log("winHeight :"+winHeight);
            var newtop = top - scrolltop;
            if(newtop>15){
                scope.top = top - scrolltop;
            }else{
                scope.top = 15;
            }
            if(oldtop!=newtop){
                scope.$apply();
            }
        }

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

        adjustTop();
    };
}]);

我想进行单元测试,根据窗口滚动检测元素top位置的调整。

以下是我的问题:

  1. 我如何模拟在单元测试中模拟窗口滚动?
  2. 如何让网页文档长于浏览器高度以启用滚动模拟?
  3. 更新

    在接受安德鲁的建议后,这是我的$window模拟:

    var mock$window;
    beforeEach(module('my-app', function ($provide) {
            mock$window = {
              scrollTop : 200,
              height: 960
            };
            $provide.value('$window', mock$window);
        })
    );
    

    当我运行测试时,我能够获得w.scrollTop()的结果,但w.height()会返回错误

      

    无法使用'in'运算符在undefined中搜索'height'。

    没有模拟,我在测试中没有得到任何JavaScript错误,但w.scrollTop()值为0,而w.height()是运行该版本的PhantomJS浏览器的浏览器窗口高度测试

    那么,如何才能在单元测试中获得w.height()模拟效果?

    以下是更好地说明问题的代码示例: http://jsfiddle.net/w4h5q5hr/

2 个答案:

答案 0 :(得分:2)

您最好的选择是提供模拟$window对象。您可以在$window子句中提供模拟beforeEach。这里的想法是你是单元测试,你可以假设$window按设计工作。

这样的事情会起作用:

var mock$window, scrollTop = 100;
beforeEach(module('my-app', function ($provide) {
            mock$window = {
              scrollTop : function() { return scrollTop; }
              bind : function(eventName, cb) { ... }
            };
            $provide.value('$window', mock$window);
        })
);

然后,在您的测试中,您可以:

  • 窥探窗口方法
  • 确保在正确的事件上调用bind
  • 确保adjustTop适当地使用不同的scrollTop值。

这足以对您的代码进行单元测试,但如果您想真正看到此代码在实际应用程序设置中有效,您可能需要尝试类似protractor的内容。

答案 1 :(得分:2)

为你想要模仿的东西创建间谍:

spyOn($window, 'scrollTop').and.returnValue(100);

如果你正在嘲笑jQuery调用,你可以像这样使用$ .fn:

spyOn($.fn, 'scrollTop').and.returnValue(100);