我有一个带有输入 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();
});
});
如何重写此测试或我的组件以使其通过?
最佳答案
生命周期 Hook ( 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 访问使 Angular 测试变得复杂,因为它需要模拟全局变量或 DOM。
关于angular - 如何对依赖于元素高度的组件进行单元测试( Angular 为 5)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48172859/