单元测试指令的控制器

Unit testing directive's controller

我正在努力从单元测试指令中获取控制器。这是我的 angular 应用程序:

angular.module('test-app', [])

    .controller('loadingCtr', ['$scope', function ($scope) {

    }])

    .directive('loading', function() {
        return {
            restrict: 'E',
            controller: 'loadingCtr'
       };
    });

这是我的单元测试代码:

describe('loading', function () {

    beforeEach(inject(function($rootScope, $compile) {

        var fooElement = $compile('<loading></loading>')($rootScope);
        var fooController = fooElement.controller('loading');

        $rootScope.$digest();
        console.log(fooController);
    })); 

    describe('loading: testing loading directive', function() {
        it('should create loading directive', function() {
        });
    });
});

这里有一个 plnkr 可以乱用:http://plnkr.co/edit/38cc5HQFgeHDhnC8OMo8?p=info

fooController 始终 returns 未定义。我已经尝试使用我在网上找到的以下示例,但我总是得到相同的结果:

Unit testing a directive that defines a controller in AngularJS

http://daginge.com/technology/2014/03/03/testing-angular-directive-controllers-with-jasmine-and-karma/

这里有什么我明显遗漏的吗?

我能看到的唯一问题是你没有在你的夹具中加载模块 test-app,这意味着编译的 html 代码并没有真正编译指令 loading 因为它在注射器中不可用。所以尝试在 beforeEach 块中加载模块。加载模块可确保在模块下注册的指令、控制器、服务等在注入器中可用,否则它只会将模块用作 ng,它对 loading 指令一无所知。

describe('loading', function () {
   var fooController;

    //Load the module 
    beforeEach(module('test-app'));

    beforeEach(inject(function($rootScope, $compile) {

        var fooElement = $compile('<loading></loading>')($rootScope);
        fooController = fooElement.controller('loading');

        $rootScope.$digest();
        console.log(fooController);
    })); 

    describe('loading: testing loading directive', function() {
        it('should create loading directive', function() {
          expect(fooController).toBeDefined();
        });
    });
});

Demo

另请注意,如果您使用 .controller 注册控制器,则可以通过 $controller(ctrlName) 构造直接获取控制器实例。如果您在指令中使用带有 bindToController:truecontrollerAs 语法,那么您也可以使用与别名相同的 属性 名称从作用域中获取它。