问题描述
如何在 Jasmine 单元测试中模拟或模拟窗口滚动和/或设置 window.pageYOffset 属性?
How can you simulate or mock window scrolling in a Jasmine Unit Test and or set a window.pageYOffset property?
我使用的是 Angular 1.3、Jasmine 2.1 + Karma 0.12.28 和 PhantomJS 1.9.12
I am using Angular 1.3, Jasmine 2.1 + Karma 0.12.28 and 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
}
});
}
}
})();
这是我的 testSpec:
And this is my testSpec:
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() 函数.但是我怎样才能对其进行单元测试?
I want to simulate or mock a window scroll event to the element.scrollHeight, because if these two reaches the same height my directive runs the loadMore() function. But how can I make unit test of that?
顺便说一句,该指令在生产中运行良好:)
Btw the directive works fine in production :)
推荐答案
最近遇到了同样的问题.为了滚动工作,您需要在 body 标签上设置一些尺寸,以便可以滚动窗口.
Had the same issue recently. For the scrolling to work, you will need to set some dimensions on the body tag, so the window can be scrolled.
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 上运行测试,您还可以使用 Chrome,将以下内容添加到您的 .travis.yml
If you are running your tests on Travis CI, you can also use Chrome by adding the following to your .travis.yml
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
以及在您的 karma 配置中的自定义 Chrome 启动器:
And a custom Chrome launcher in your karma config:
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 );
};
这篇关于如何在 Angular 单元测试中模拟窗口滚动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!