在Angular 2中测试ngOnChanges生命周期挂钩 [英] Testing ngOnChanges lifecycle hook in Angular 2

查看:296
本文介绍了在Angular 2中测试ngOnChanges生命周期挂钩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码,我尝试测试Angular2的ngOnChanges生命周期挂钩:

Given the following code I try to test the ngOnChanges lifecycle hook of Angular2:

import {
    it,
    inject,
    fdescribe,
    beforeEachProviders,
} from '@angular/core/testing';

import {TestComponentBuilder} from '@angular/compiler/testing';

import {Component, OnChanges, Input} from '@angular/core';

@Component({
    selector: 'test',
    template: `<p>{{value}}</p>`,
})
export class TestComponent implements OnChanges {
    @Input() value: string;

    ngOnChanges(changes: {}): any {
        // should be called
    }
}

fdescribe('TestComponent', () => {
    let tcb: TestComponentBuilder;

    beforeEachProviders(() => [
        TestComponentBuilder,
        TestComponent,
    ]);

    beforeEach(inject([TestComponentBuilder], _tcb => {
        tcb = _tcb;
    }));

    it('should call ngOnChanges', done => {
        tcb.createAsync(TestComponent).then(fixture => {
            let testComponent: TestComponent = fixture.componentInstance;

            spyOn(testComponent, 'ngOnChanges').and.callThrough();

            testComponent.value = 'Test';
            fixture.detectChanges();

            expect(testComponent.ngOnChanges).toHaveBeenCalled();
            done();
        }).catch(e => done.fail(e));
    });
});

不幸的是,测试失败并显示消息Expected spy ngOnChanges to have been called.,我知道我可以在此示例中检查HTML元素的内容,但是我有一些代码需要在ngOnChanes生命周期挂钩中进行测试,因此我的解决方案.我也不想直接在测试中致电testComponent.ngOnChanges({someMockData});.

Unfortunately the test fails with the message Expected spy ngOnChanges to have been called. I know that I could just check the contents of the HTML Element in this example, but I have some code that needs to be tested inside of the ngOnChanes lifecycle hook, so thats not a solution for me. I also don't want to call testComponent.ngOnChanges({someMockData}); in the test directly.

如何从测试中设置TestComponent.value以便调用ngOnChanges?

How can I set the TestComponent.value from a test so that ngOnChanges is called?

推荐答案

猜猜我参加聚会有点晚了,但这对将来的某个人可能有用.

Guess I'm a little late to the party, However this may be useful to some one in the future.

自从发布RC 5角度以来,对测试进行了一些更改.但是,当以编程方式设置输入时,此处的主要问题是ngOnChanges不会被调用.

There have been a few changes to testing since RC 5 of angular has been released. However the main issue over here is ngOnChanges is not called when inputs are set programmatically. See this for more info . Basically the OnChanges hook is triggered when inputs are passed via the view only.

对此的解决方案是拥有主机组件,该主机组件将成为测试组件的父组件,并将输入传递给主机组件的模板.

The solution to this would be to have host component which would be the parent of the test component and pass inputs to through the host component's template.

这是完整的工作代码:

import {Component, OnChanges, Input, ViewChild} from '@angular/core';
import { TestBed }      from '@angular/core/testing';

@Component({
    selector: 'test',
    template: `<p>{{value}}</p>`,
})
export class TestComponent implements OnChanges {
    @Input() value: string;

    ngOnChanges(changes: {}): any {
        // should be called
    }
}
/* In the host component's template we will pass the inputs to the actual
 * component to test, that is TestComponent in this case
 */
@Component({
    selector : `test-host-component`,
    template :
    `<div><test [value]="valueFromHost"></test></div>`
})
export class TestHostComponent {
    @ViewChild(TestComponent) /* using viewChild we get access to the TestComponent which is a child of TestHostComponent */
    public testComponent: any;
    public valueFromHost: string; /* this is the variable which is passed as input to the TestComponent */
}

describe('TestComponent', () => {

    beforeEach(() => {
        TestBed.configureTestingModule({declarations: [TestComponent,TestHostComponent]}); /* We declare both the components as part of the testing module */
    });

    it('should call ngOnChanges', ()=> {
        const fixture = TestBed.createComponent(TestHostComponent);
        const hostComponent = fixture.componentInstance;
        hostComponent.valueFromHost = 'Test';
        const component = hostComponent.testComponent;
        spyOn(component, 'ngOnChanges').and.callThrough();
        fixture.detectChanges();
        expect(component.ngOnChanges).toHaveBeenCalled();
    })


});

这篇关于在Angular 2中测试ngOnChanges生命周期挂钩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆