簡體   English   中英

如何在 Angular 單元測試中模擬 window 滾動?

[英]How to simulate window scrolling in a Angular Unit Test?

如何在 Jasmine 單元測試中模擬或模擬 window 滾動和/或設置 window.pageYOffset 屬性?

我正在使用 Angular 1.3、Jasmine 2.1 + Karma 0.12.28 和 PhantomJS 1.9.12

這是我的指令:

'use strict';
(function () {
angular
  .module('myApp')
  .directive('scrollNews', scrollNews);

  function scrollNews(){

    var directive = {
      restrict: 'A',
      scope: false,
      link: link
    };

    return directive;

    function link(scope, element) {
      scope.limit = 2;
      //add one to the limit
      scope.loadMore = function() {
        scope.limit += 1;
      };

      var raw = element[0];
      angular.element(window).on('scroll', function () {
        var scrollFrontier = this.pageYOffset + 800;
        // when scrollFrontier has reached raw.scrollHeight, run loadMore()
        if (scrollFrontier >= raw.scrollHeight) {
          scope.loadMore(); // run the function
          scope.$digest(); // update the HTML
        }
      });
    }
  }
})();

這是我的測試規范:

describe('Directive: scroll news', function(){

  var element, $scope, $window;

  beforeEach(module('myApp'));

  beforeEach(inject(function($compile, $rootScope, _$window_){
    $scope = $rootScope;
    $window = _$window_;

    element = angular.element('<div scroll-news></div>');
    $compile(element)($scope);
    $scope.$digest();
  }));

  it('should have a limit of 2 when no scrolling have occurred', function(){
    expect($scope.limit).toBe(2);
  });

  it('should add one to the limit with loadMore function', function(){
    $scope.loadMore();
    expect($scope.limit).toBe(3);
  });

  it('should run loadMore() when scrolling has reached a specific height', function(){
    element.scrollHeight = 1400;

    var spy = spyOn($window, 'scrollTo');
    $window.scrollTo(0, 1400);
    expect(spy).toHaveBeenCalled();

   expect($scope.limit).toBe(3); // Logs: Expected 2 to be 3. - so loadMore() have not called
 });
});

我想模擬或模擬 element.scrollHeight 的 window 滾動事件,因為如果這兩個達到相同的高度,我的指令將運行 loadMore() function。但是我如何對其進行單元測試?

順便說一句,該指令在生產中運行良好:)

最近有同樣的問題。 為了使滾動正常進行,您需要在body標簽上設置一些尺寸,以便可以滾動窗口。

var scrollEvent = document.createEvent( 'CustomEvent' ); // MUST be 'CustomEvent'
scrollEvent.initCustomEvent( 'scroll', false, false, null );

var expectedLeft = 123;
var expectedTop = 456;

mockWindow.document.body.style.minHeight = '9000px';
mockWindow.document.body.style.minWidth = '9000px';
mockWindow.scrollTo( expectedLeft, expectedTop );
mockWindow.dispatchEvent( scrollEvent );

不幸的是,這在PhantomJS中不起作用

如果您正在Travis CI上運行測試,則還可以通過將以下內容添加到.travis.yml中來使用Chrome

before_install:
   - export CHROME_BIN=chromium-browser
   - export DISPLAY=:99.0
   - sh -e /etc/init.d/xvfb start

在業力配置中添加一個自定義Chrome啟動器:

module.exports = function(config) {
    var configuration = {

        // ... your default content

        // This is the new content for your travis-ci configuration test
        //  Custom launcher for Travis-CI
        customLaunchers: {
            Chrome_travis_ci: {
                base: 'Chrome',
                flags: ['--no-sandbox']
            }
        },

        // Continuous Integration mode
        // if true, it capture browsers, run tests and exit
        singleRun: true 
    };

    if(process.env.TRAVIS){
        configuration.browsers = ['Chrome_travis_ci'];
    }

    config.set( configuration );

};

我使用並奏效的策略只是增加屏幕的大小,使用document.body.style.minHeight ,在某種程度上你將遵守你的偏移條件,然后你驗證你的邏輯是否被執行:

    spyOn($scope, 'loadMore').and.callThrough();
    const screenSizeBy2 = document.documentElement.clientHeight * 2;
    document.body.style.minHeight = screenSizeBy2 + 'px';

    expect(scope.loadMore).not.toHaveBeenCalled();

    window.scrollTo(0, document.documentElement.clientHeight);
    fixture.detectChanges();

    expect($scope.loadMore).not.toHaveBeenCalledTimes(1);

我無法針對您的特定情況測試代碼,但我希望您能理解

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM