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

How to ensure controller is injected into directive for test?

我正在使用 Smart Table 并尝试使用 Karma 设置一些测试。我反复收到错误 Error: [$compile:ctreq] Controller 'stTable', required by directive 'removePag', can't be found!。实际使用该指令时我没有收到任何错误。在我看来,Karma 应该使 smart-table 可用于 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 非常相似。模仿聪明的 tables 测试他们自己的控制器的方式也不起作用,正如那里所建议的那样。无论如何,模块源代码中的 stTable 似乎是指令,而不是控制器。

我也试过在测试中用 st-table 包裹元素,像 $compile("<table st-table><remove-pag>... 一样有同样的错误。

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

显然,问题是父 必须 被嘲笑。 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");
});