在Angular 2中测试ngOnChanges生命周期挂钩 [英] Testing ngOnChanges lifecycle hook in Angular 2
问题描述
给出以下代码,我尝试测试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屋!