如何对一个取决于元素高度的组件进行单元测试(带角度5)?

时间:2018-01-09 16:43:11

标签: angular unit-testing typescript jasmine

我有一个输入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();
  });
});

如何重写此测试或我的组件以便通过?

1 个答案:

答案 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。