如何在单元测试中从编译元素中获取角度控制器参考?

时间:2014-07-16 18:04:15

标签: angularjs unit-testing directive

放弃ngMockE2E能够从$ httpBackend提供正确的passThrough()后,我已经手动将模板添加到缓存中。如果我想“测试”我的模板,这似乎工作得很好。但是,假设我想在控制器上测试一些被调用的条件(通过指令),我如何得到它的引用?

describe('RedactedFilter ', function() {

    var ctrl, filterModel,createController;

    var $httpBackend,$scope,template, $templateCache,$compile,$rootScope, $compile;

    beforeEach(module('RedactedApp.Services'));
    beforeEach(module('RedactedApp.Controllers'));
    beforeEach(module('RedactedApp.Models'));

    beforeEach(inject(function($templateCache,_$compile_,_$rootScope_) {

        //assign the template to the expected url called by the directive and put it in the cache
        template = $templateCache.get('src/main/app/components/redactedFilter/redacted-filter.tpl.html');
        $templateCache.put('src/main/app/components/redactedFilter/redactedFilter-filter.tpl.html',template);

        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));



    beforeEach(inject(function ($controller, $rootScope,_$q_, $injector, _$compile_) {

        $scope = $rootScope.$new();
        $httpBackend = $injector.get('$httpBackend');
        $compile = _$compile_;

        filterModel = $injector.get('RedactedFilterModel');
    }));

    it('should default to tab 0', function() {

        var formElement = angular.element('<redacted-filter></redacted-filter>');
        var element = $compile(formElement)($rootScope);
        $rootScope.$digest();

        var ctrl = element.controller();

        //ctrl is undefined
        expect(ctrl.selectedTab).toEqual(0);
    });

});

请注意,它没有说未定义函数controller(),而是调用它的结果。我的指令将replace设置为false,因此我不认为隐藏元素的转换是一个问题。

这是我的好措施指令:

angular.module('RedactedApp.Directives').directive('redactedFilter', function(){
        return {
            restrict: 'E',
            replace: false,
            templateUrl: '../../main/app/components/redactedFilter/redacted-filter.tpl.html'
        };
    });

1 个答案:

答案 0 :(得分:0)

首先,在运行测试之前,使用ng-html2j或ng-templates将模板推送到模板缓存中。

然后将模板编译成元素,并将它们推送到控制器中进行测试:

beforeEach(inject(function($templateCache,_$compile_,_$rootScope_, _$controller_) {

    //get the template from the cache
    template = $templateCache.get('src/main/app/components/someController/widget-search.tpl.html');

    $compile = _$compile_;
    $rootScope = _$rootScope_;
    $controller = _$controller_;

    //compile it
    element = $compile(template)($rootScope);
}));

 //then shove your compiled element into your controller instance



it( 'should be instantiated since it does not do much yet', function(){

            ctrl = $controller('SomeController',
                {
                    $scope: $rootScope.$new(),
                    $element: element
                });

            expect( ctrl.hasInstance).toBeTruthy();

        });