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

前端 未结 3 975
独厮守ぢ
独厮守ぢ 2021-02-13 04:20

I\'m using Angular 1.5.5 and Jasmine as test framework. Currently I have to do something like this so that the test passes:

function createController(bindings) {         


        
相关标签:
3条回答
  • 2021-02-13 04:45

    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

    0 讨论(0)
  • 2021-02-13 04:57

    There is an issue in github regarding this: https://github.com/angular/angular.js/issues/14129

    Basically it is working as intended, not calling $onInit or $onChanges automatically.

    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). 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).

    0 讨论(0)
  • 2021-02-13 04:58

    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();
            }));
        });
    });
    
    0 讨论(0)
提交回复
热议问题