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

Gre*_*ion 15 unit-testing angularjs

我使用Angular 1.5.5和Jasmine作为测试框架.目前我必须做这样的事情,以便测试通过:

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);
    });

});
Run Code Online (Sandbox Code Playgroud)

Gus*_*tav 7

github中存在一个问题:https://github.com/angular/angular.js/issues/14129

基本上它是按预期工作,而不是呼叫$onInit$onChanges自动.

执行$ onInit没有任何意义(或低意义),我解释一下:$ componentController是实例控制器的一种替代$ controller,但它不是创建由controllerProvider注册的控制器实例,而是创建通过注册的控制器实例指令(满足组件定义的指令).因此,一旦你拥有控制器的实例,就可以手动调用$ onInit,以及控制器的所有生命周期,这个想法是你正在测试控制器,而不是指令(及其关系).


ela*_*ash 0

我不知道这是否有帮助,但为了测试组件,我执行以下操作

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 });
}));
Run Code Online (Sandbox Code Playgroud)

$onInit() 和 $onChanges() 在它们应该被触发的时候被触发

  • 从我在这里读到的内容来看,您正在编译一个组件,然后请求该组件的控制器的实例,但不一定是该组件编译时使用的控制器的实例(如果这有意义的话)。IOW,`$compile()`正在创建一个控制器,然后您使用`$componentController`创建*另一个*控制器。它是相同的控制器类,但与“$compile”创建的类实例不同。我认为更好的方法是“angular.element(...).controller()”,它将为您提供与组件关联的控制器。 (7认同)