简体   繁体   English

如何在单元测试Angular组件控制器中隐含地触发$ onInit或$ onChanges?

[英]How to trigger $onInit or $onChanges implictly in unit testing Angular component controller?

I'm using Angular 1.5.5 and Jasmine as test framework. 我使用Angular 1.5.5和Jasmine作为测试框架。 Currently I have to do something like this so that the test passes: 目前我必须做这样的事情,以便测试通过:

function createController(bindings) {
    return $componentController('myController', null, bindings);
}

beforeEach(inject(function (_$componentController_) {
    $componentController = _$componentController_;
}));

describe('on pages updated', function () {

    beforeEach(function () {
        controller = createController({prop1: 0, prop2: 0});
        controller.$onInit(); // you see I have to explitcitly call this $onInit function
    });

    it('should update isSelected and currentPage', function () {
        expect(controller.prop1).toBe(0);
        expect(controller.prop2).toBe(0);

        controller.prop1= 1;
        controller.prop2= 2;
        controller.$onChanges(controller); // and $onChanges here as well

        expect(controller.prop1).toBe(1);
        expect(controller.prop2).toBe(2);
    });

});

There is an issue in github regarding this: https://github.com/angular/angular.js/issues/14129 github中存在一个问题: https//github.com/angular/angular.js/issues/14129

Basically it is working as intended, not calling $onInit or $onChanges automatically. 基本上它按预期工作,而不是自动调用$onInit$onChanges

it makes no sense (or low sense) to execute $onInit, I explain it: $componentController is to instance controllers a kind of replacement for $controller, but instead of creating instances of controllers registered by the controllerProvider it creates instances of controllers registered through directives (the ones that satisfies a component definition). 执行$ onInit没有任何意义(或低意义),我解释一下:$ componentController是实例控制器的一种替代$ controller,但它不是创建由controllerProvider注册的控制器实例,而是创建通过注册的控制器实例指令(满足组件定义的指令)。 So, once you have the instance of the controller, you can call manually $onInit, and all the lifecycle of your controller, the idea is that you are testing a controller, not a directive (and its relationships). 因此,一旦你拥有控制器的实例,就可以手动调用$ onInit,以及控制器的所有生命周期,这个想法是你正在测试控制器,而不是指令(及其关系)。

I don't know if this will help, but for testing components I do the following 我不知道这是否会有所帮助,但对于测试组件,我会执行以下操作

beforeEach(module('templates'));

var element;        
var scope;

beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();
    scope.draw = new ol.source.Vector({ wrapX: false });
    element = angular.element('<custom-element draw="draw"></custom-element>');
    element = $compile(element)(scope);
}));

var controller;
beforeEach(inject(function ($rootScope, $componentController) {
    scope = $rootScope.$new();
    scope.draw = new ol.source.Vector({ wrapX: false });
    controller = $componentController('customElement', {draw: new ol.source.Vector({ wrapX: false })}, { $scope: scope });
}));

and $onInit() and $onChanges() get triggered when they should be, by themselves 并且$ onInit()和$ onChanges()会在它们本身应该被触发时被触发

You would require to take reference of controller from compiled version of element. 您需要从编译版本的元素中引用控制器。 As shown below: 如下所示:

describe('Component: Test Method', function () {

        beforeEach(inject(function (_$rootScope_) {
            scope = _$rootScope_.$new();
        }));


        it('should set value of selectedPackage to null after $onChanges event', inject(function ($compile) {
            // Trigger 1st $onChanges
            scope.selectedPackage = 'packageCode';

            var element = angular.element('<select-my-tv selected-package="selectedPackage"></select-my-tv>');
            element = $compile(element)(scope);
            scope.$digest();

            //Extract the Controller reference from compiled element
            var elementController = element.isolateScope().$ctrl;

            // Assert
            expect(elementController.selectedPackage).toBeNull();
        }));
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM