2015-04-04 4 views
1

У меня есть директивы, которые выглядят так:AngularJS - Unit Test с ОС Windows прокруткой

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. Как я могу заставить документ веб-страницы быть длиннее, чем высота браузера, чтобы включить симуляцию прокрутки?

Update:

После взятия советы Эндрю, это мой $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() возвращает ошибку

Cannot use 'in' operator to search for 'height' in undefined.

Без насмешки я не получаю ошибки JavaScript в тесте, но значение w.scrollTop() равно 0, а w.height() - это высота окна браузера браузера PhantomJS, выполняющего тест.

Итак, как я могу получить макетные работы w.height() в модульных тестах?

Вот пример кода, чтобы лучше проиллюстрировать проблему: http://jsfiddle.net/w4h5q5hr/

ответ

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); 
     }) 
); 

Затем в тестах, вы можете:

  • шпионить методов окна
  • убедитесь, что привязка называется на соответствующую событию
  • убедитесь, что adjustTop работает соответствующим образом с различными значениями scrollTop.

Этого достаточно для модульного тестирования кода, но если вы действительно хотите увидеть, что этот код работает в реальной обстановке приложения, вы можете попробовать что-то вроде protractor.

+0

Спасибо большое для вашего ответа, но, похоже, это не работает. Когда я пытался отключить log 'w.scrollTop()', он возвращает 'function() {return scrollTop; } '. Кроме того, ложный объект '$ window', похоже, не работает с' $ window.height() ', что я получаю ошибку:' Невозможно использовать 'в' operator для поиска 'height' в undefined' Итак, как mock '$ window' правильно? Спасибо. – user1995781

+0

Вы должны издеваться над этими методами. включить их в mock $ window. –

+0

Привет, Андрей, я обновил свой вопрос, чтобы лучше объяснить ситуацию. Надеюсь, вы можете помочь здесь. Спасибо. – user1995781

2

Создание spys для вещей, которые вы хотите, чтобы дразнить, как:

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

Если вы насмешливый JQuery вызовы, которые вы можете использовать $ .fn так:

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