如何确保控制器注入指令进行测试?

时间:2016-03-01 21:11:08

标签: angularjs angularjs-directive karma-jasmine smart-table

我正在使用Smart Table并尝试使用Karma设置一些测试。我反复收到错误Error: [$compile:ctreq] Controller 'stTable', required by directive 'removePag', can't be found!。实际使用该指令时,我没有收到任何错误。在我看来,Karma应该为tools模块提供智能表,这是我在规范中提到的,但没有骰子。我如何确保stTable可以在测试中使用removePag

在tools.js中(包括expose,因为我怀疑它可能会涉及,因为它是一个链接到顶级st-table的指令):

angular.module('tools', ['smart-table'] );

angular
    .module('freeTools')
        .directive('expose', exposeTableState)
        .directive('removePag', removePag)

function exposeTableState(){
    return {
        require:'stTable',
            link:function(scope, element, attr, ctrl){
            scope.smartTableState=ctrl.tableState();
        }
    };
}

function removePag() {
    return {
        restrict: 'E',
        require: '^stTable',
        template: '<a href="">View as a single page</a>',
        link: function(scope, element, attrs, ctrl) {
            return element.bind('click', function () {
                return scope.$apply(function () {
                    var tableState;
                    tableState = ctrl.tableState();
                    tableState.pagination.number = tableState.pagination.totalItemCount;
                    return ctrl.pipe();
                });
            });

        }
      };
}

在toolsSpec.js中:

describe('tools', function () {
    var $compile,
    $rootScope;
    beforeEach(module('freeTools'));
    beforeEach(inject(function(_$compile_, _$rootScope_){
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

    it('Replaces the element with the appropriate content', function() {
        var element = $compile("<remove-pag></remove-pag>")($rootScope);
        $rootScope.$digest();
        expect(element.html()).toContain("View as a single page");
    });
}

在Karma.conf中:

module.exports = function(config){
config.set({

basePath : '../../',

files : [
    'bower_components/jquery/dist/jquery.js',
    'bower_components/angular/angular.js',
    'bower_components/angular-smart-table/dist/smart-table.js',
    'bower_components/angular-mocks/angular-mocks.js',
    'assets/scripts/*.js',
    'assets/test/*.js'
],

autoWatch : true,

frameworks: ['jasmine-ajax', 'jasmine'],

browsers : ['Chrome'],

plugins : [
        'karma-chrome-launcher',
        'karma-firefox-launcher',
        'karma-jasmine-ajax',
        'karma-jasmine',
        ],
});
};

简化的html:

<section ng-app="tools">
  <table st-table="data" st-safe-src="safe" expose>
    <div st-pagination>
      <remove-pag></remove-pag>

我意识到问题与Unit testing an AngularJS (Smart Table) directive非常相似。模仿智能表测试自己的控制器的方式也没有,正如那里所建议的那样。无论如何,模块源代码中的stTable似乎是指令,而不是控制器。

我还尝试在测试中使用st-table包装元素,例如$compile("<table st-table><remove-pag>...,但错误相同。

我已经查看了Controller Required By Directive Can't Be Found等问题,但我已经有了共享父级tools

1 个答案:

答案 0 :(得分:0)

问题显然是父必须被嘲笑。 H / t到Unit testing AngularJS child directive that requires parent directive有关模拟的指导。

it('Replaces the element with the appropriate content', function() {
    // This can be anything, even an empty object.
    var stTableControllerMock = {
        idk: function () {
            return 'something';
        }
    };

    // Create element with dummy parent
    var element = angular.element('<fake-parent><remove-pag></remove-pag></fake-parent>');

    // '$' + {nameOfMissingController} + 'Controller' = '$stTableController'
    element.data('$stTableController', stTableControllerMock);

    // Compile, find the element we're testing, and digest
    $compile(element)($rootScope.$new());
    element = element.find('remove-pag');
    $rootScope.$digest();

    // Test
    expect(element.html()).toContain("View as a single page");
});