【问题标题】:How to simulate window scrolling in a Angular Unit Test?如何在 Angular 单元测试中模拟窗口滚动?
【发布时间】:2023-03-13 00:50:01
【问题描述】:

如何在 Jasmine 单元测试中模拟或模拟窗口滚动和/或设置 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 的窗口滚动事件,因为如果这两个达到相同的高度,我的指令将运行 loadMore() 函数。但是我怎样才能对它进行单元测试呢?

顺便说一句,该指令在生产中运行良好:)

【问题讨论】:

标签: angularjs unit-testing jasmine phantomjs karma-runner


【解决方案1】:

最近遇到了同样的问题。为了滚动工作,您需要在 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 启动器在您的 karma 配置中:

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

};

【讨论】:

    【解决方案2】:

    我使用并且有效的策略只是增加屏幕的大小,使用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);
    

    我无法针对您的特殊情况测试代码,但我希望您能明白

    【讨论】:

      猜你喜欢
      • 2018-11-24
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      相关资源
      最近更新 更多