在作为普通旧函数传递时测试指令控制器

时间:2015-12-02 11:56:05

标签: angularjs karma-runner

为了更加像Angular 2.0,我决定以传统的方式消除对控制器的定义:

e.g。

return {
   restrict: 'E',
   controller: 'MyCtrl',
   controllerAs: 'vm',
   bindToController: true,
   scope: {},
   templateUrl: 'path/to/tempate.html'
}

在这里我们可以看到控制器名称作为字符串传递,这意味着我们在某处定义了类似的内容:

app.controller('MyCtrl', function(...));

在传统测试中,我只是将$controller服务注入测试中以检索MyCtrl控制器。但是我决定这样做:

return {
   restrict: 'E',
   controller: MyCtrl,
   controllerAs: 'vm',
   bindToController: true,
   scope: {},
   templateUrl: 'path/to/tempate.html'
}

这里唯一的区别是传递给控制器​​声明的是一个名为MyCtrl的函数。这似乎一切都很好,但是你会去检索这个控制器并进行测试吗?

我试过这样做:

var $compile, $rootScope, $httpBackend, element, ctrl;

    beforeEach(module('app'));
    beforeEach(function() {
        inject(function(_$compile_, _$rootScope_, _$httpBackend_) {
            $compile     = _$compile_;
            $rootScope   = _$rootScope_.$new();
            $httpBackend = _$httpBackend_;

            element = $compile('<directive></directive>')($rootScope);
            ctrl = element[0].controller;
        });
   });

但是在上面我得到 undefined 回来给控制器。有没有其他人让这一举动更像Angular 2.0?在测试方面有什么不同?

由于

P.S语法更改的想法是,在我们这样做时,可以轻松升级到Angular 2.0。

修改

我花了最后一两天试图检索控制器,唯一有效的方法似乎只是以传统方式传递控制器。这是我尝试过的方法列表(请参阅评论以确定每个输出的内容)

(function() {
'use strict';

/*
    This part is used just for testing the html rendered
*/
describe('flRequestPasswordReset template: ', function() {

    var $compile, $rootScope, $templateCache, template, element, ctrl;
    var path = 'templates/auth/fl-request-password-reset/fl-request-password-reset.html';

    beforeEach(module('app'));
    beforeEach(module(path));

    beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_) {
        $compile        = _$compile_;
        $rootScope      = _$rootScope_;
        $templateCache  = _$templateCache_;

        // Using nghtml2js to retrieve our templates
        template = $templateCache.get(path);
        element = angular.element(template);
        $compile(element)($rootScope.$new());
        $rootScope.$digest();

        // $rootScope has a reference to vm which is what my  
        // controllerAs defines but only contains one of the variables

        // This returns undefined
        ctrl = element.controller('flRequestPasswordReset');
    }));

    it('should be defined', function() {
        expect(element).toBeDefined();
    });
});

describe('flRequestPasswordReset: template with controller: ', function() {

    var $compile, $rootScope,  $httpBackEnd, element, ctrl;
    var path = '/templates/auth/fl-request-password-reset/fl-request-password-reset.html';

    beforeEach(module('app'));      

    beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_, _$httpBackend_) {
        $compile        = _$compile_;
        $rootScope      = _$rootScope_;
        $httpBackEnd    = _$httpBackend_;

        $httpBackEnd.expectGET(path).respond({});

        element = angular.element('<fl-request-password-reset></fl-request-password-reset>');
        $compile(element)($rootScope.$new());
        $rootScope.$digest();

        // Uses alternate name for directive but still doesn't get the 
        // controller
        ctrl = element.controller('fl-request-password-reset');
    }));

    it('should be defined', function() {
        expect(element).toBeDefined();
    });
});

/* 
    This part is used for testing the functionality of the controller by itself
*/
xdescribe('flRequestPasswordReset: just controller', function() {
    var scope, ctrl;

    beforeEach(module('app'));
    beforeEach(inject(function($controller, $rootScope) {
        scope = $rootScope;
        // Instantiate the controller without the directive
        ctrl  = $controller('FlRequestPasswordResetController', {$scope: scope, $element: null});
    }));

    it('should be defined', function() {
        expect(true).toBe(true);
    });

    /*
    This works because I moved the controller back to the old way
    */
});

}());

根据我对pkozlowski.opensource下的this问题的理解,您可以使用将控制器作为函数传递,只要您不将其封装在指令中。这种方式在全球范围内暴露出来。这是一件坏事,因为它污染了全局命名空间,但他似乎建议在构建应用程序时将其包装起来。

我对此的理解是否正确?

0 个答案:

没有答案