我有一个输入fsElement
的组件。这个fsElement
应该是任何html元素的id。然后我的组件使用此提供的id来获取元素的高度。以下是相关代码:
export class BotaoTelaCheiaComponent implements OnInit {
@Input() fsElement:string;
private _originalHeight: number;
constructor() { }
ngOnInit() {}
ngAfterViewInit() {
this._originalHeight = document.getElementById(this.fsElement).clientHeight;
}
}
当我运行ng test
时,TypeError: Cannot read property 'clientHeight' of null
失败。我正在运行angular cli生成的标准测试:
describe('BotaoTelaCheiaComponent', () => {
let component: BotaoTelaCheiaComponent;
let fixture: ComponentFixture<BotaoTelaCheiaComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BotaoTelaCheiaComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BotaoTelaCheiaComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
如何重写此测试或我的组件以便通过?
答案 0 :(得分:2)
生命周期挂钩(OnInit
等)在第一次更改检测时触发,该检测在beforeEach
中执行。
为了避免这种情况,fixture.detectChanges()
应该从beforeEach
中移除并按需调用。
it('should create', () => {
expect(component).toBeTruthy();
component.fsElement = 'foo';
spyOn(document, 'getElementById').and.returnValue({ clientHeight: 100 });
fixture.detectChanges();
expect(document.getElementById).toHaveBeenCalledWith('foo');
expect(component['_originalHeight']).toBe(100);
});
或者,可以将id="foo"
的真实DOM元素添加到beforeEach
中的DOM中,并在afterEach
中删除。
直接DOM访问使角色测试变得复杂,因为它需要模拟全局或DOM。