2

我正在尝试测试一个指令,该指令允许我在我的应用程序中进行无限滚动。该指令在我的生产代码中运行良好。

这个问题非常接近How to test AngularJS Directive with scrolling如果有人说它们是相同的问题,我将删除这个问题。但是,它并没有解决我的问题(至少我不知道如何解决)。

这是我的指令

(function(){
    "use strict";
    angular.module('moduleA').directive('whenScrolled',Directive);

    Directive.$inject = [];

    function Directive(){
        return {
            restrict : 'A', // Restrict to Attributes
            link : postLink
        };

        // Bind the element's scroll event
        function postLink(scope,elem,attr){
            var raw = elem[0];
            elem.bind('scroll',eventMethod);

            function eventMethod(){
                if ( raw.scrollTop + raw.offsetHeight >= raw.scrollHeight ) {
                    scope.$apply(attr.whenScrolled);
                }
            };
        };
    };

})();

这是我的业力测试

describe('whenScrolled Directive:',function(){

    beforeEach(module('moduleA'));

    // Create a list in HTML and force overflow for a scroll event
    var html = 
    '<div id="test" ' + 
    '     style="max-height:30px;overflow-y:scroll;" ' +
    '     when-scrolled="testScroll()">' + 
    '    <ul>' + 
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '        <li>Testing</li>' +
    '    </ul>' + 
    '</div>';

    var $rootScope,
        element;

    beforeEach(inject([
        '$compile','$rootScope',
        function($compile,$rs){
            $rootScope = $rs;
            $rootScope.isScrolled = false;
            $rootScope.testScroll = function(){
                $rootScope.isScrolled = true;
            };

            element = $compile(html)($rootScope);
            $rootScope.$digest();
        }
]));

    it('should activate on scroll',function(){
        expect(element).toBeDefined();
        $rootScope.$broadcast('scroll'); <-- does nothing? -->
        expect($rootScope.isScrolled).toBe(true); <-- fails -->
    });

});

我的karma.conf.js

// Created May 04, 2016
module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
      'vendor/angular/angular.js',
        'vendor/angular/angular-mocks.js', 
        'moduleA/moduleA.view.html',
        'moduleA/moduleA.module.js',
        'moduleA/moduleA.controller.js',
        'moduleB/moduleB.view.html',
        'moduleB/moduleB.module.js',
        'moduleB/moduleB.controller.js',
        'test/module-A-tests.js',
        'test/module-B-tests.js'
    ],


    // list of files to exclude
    exclude: [
      'vendor/bootstrap*',
      'vendor/jquery*',
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-    preprocessor
    preprocessors: {
        // karma-ng-html2js-preprocessor for templates in directives
        'moduleA/moduleA.form.view.html': 'ng-html2js',
        'moduleB/moduleB.view.html': 'ng-html2js'
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

我的想法是,如果我让 $rootScope 广播“滚动”到它的所有子项(在我的例子中是 $scope),并且 $scope 通过我的指令绑定到我的元素,那么这将触发我提供的方法(doScrollFn ),并且 $scope.isScrolled 会改变。

但据我所知, doScrollFn 永远不会被触发。

4

1 回答 1

3

我仍然不是 100% 确定我做错了什么,但是在谷歌搜索 karma-ng-html-preprocessor 之后,我发现了这个:

https://www.npmjs.com/package/karma-ng-html2js-preprocessor-with-templates这导致我:

https://github.com/vojtajina/ng-directive-testing这导致我:

https://angularjs.org/#create-components主要是这个:

https://github.com/vojtajina/ng-directive-testing/blob/start/test/tabsSpec.js

这是我的有效测试:

describe('whenScrolled Directive',function(){

    beforeEach(module('moduleA'));

    var html = 
        '<div id="test" ' +
        '       style="min-height:5px;max-height:30px;overflow-y:scroll;" ' +
        '     when-scrolled="testScroll()">' +
        '   <ul>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '       <li>Testing</li>' +
        '   </ul>' + 
        '</div>';

    var $rootScope,
        element;

    beforeEach(function(){
        inject([
            '$compile','$rootScope',
            function($compile,$rs){
                $rootScope = $rs;
                $rootScope.isScrolled = false;
                $rootScope.testScroll = function(){
                    $rootScope.isScrolled = true;
                };

                element = angular.element(html);
                $compile(element)($rootScope);
                $rootScope.$digest();
            }
    ]);
    });

    it('should activate on scroll',function(){
        expect(element.find('li').length).toBe(10);
        element.triggerHandler('scroll');
        expect($rootScope.isScrolled).toBe(true);
    });

});

如果这可以为​​任何人节省一些时间和麻烦,那么值得写。

于 2016-06-09T16:41:26.537 回答