具有控件属性的视频标签会导致单元测试失败

时间:2019-03-14 18:59:25

标签: javascript angular unit-testing html5-video karma-jasmine

我正在使用Angular 7.2.4构建一个Webapp。我正在使用角度CLI(7.3.1)随附的默认单元测试库。

在单元测试运行时,我一直将此错误视为失败: An error was thrown in afterAll\nResizeObserver loop limit exceeded thrown

其中一个视频输入的controls属性似乎是造成此问题的原因。如果我删除了控件属性,则所有测试都会通过。我不知道如何解决此问题,因为我需要使用视频控件。

有人可以在不构建自定义视频播放器的情况下为我指出正确的解决方法吗?

作为参考,这里是组件(实际上只是视频播放器的包装)

video.component.html

<video preload="auto"
       controls
       #videoPlayer
       controlsList="nodownload"
       (ended)="videoEnded($event)">
  <source [src]="getVideoSource()" type="video/mp4"/>
</video>

video.component.ts

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

import {ConfigService} from '../config.service';

@Component({
  selector: 'app-video',
  templateUrl: './video.component.html',
  styleUrls: ['./video.component.scss']
})
export class VideoComponent implements OnInit, OnChanges {

  @ViewChild('videoPlayer') videoPlayer: ElementRef;
  @Input() src: string;
  @Input() ended: (event: Event) => void;

  constructor(private cs: ConfigService) {
  }

  ngOnInit() {
    this.videoPlayer.nativeElement.src = this.getVideoSource();
  }

  ngOnChanges() {
    this.videoPlayer.nativeElement.src = this.getVideoSource();
  }

  getVideoSource(): string {
    return this.cs.getConfig('videosUrl') + this.src;
  }

  videoEnded($event) {
    if (this.ended) {
      this.ended($event);
    }
  }

}

video.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { VideoComponent } from './video.component';

describe('VideoComponent', () => {
  let component: VideoComponent;
  let fixture: ComponentFixture<VideoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ VideoComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(VideoComponent);
    component = fixture.componentInstance;
    component.src = '';
    component.ended = () => {};
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  afterEach(() => {
    fixture.destroy();
  });

});

更新:这似乎是Chrome问题。在Firefox或Safari浏览器中不会发生这种情况

2 个答案:

答案 0 :(得分:0)

我遇到了完全相同的问题。我还在视频标记上创建了一个包装器组件,但测试失败并出现相同的错误,问题还出在'controls'属性上。

虽然我找不到原因。

我为测试实现了一种解决方法,其中我用TestBed.overrideComponent()覆盖了控制器的模板

在这种情况下,将如下所示:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { VideoComponent } from './video.component';

describe('VideoComponent', () => {
  let component: VideoComponent;
  let fixture: ComponentFixture<VideoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ VideoComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.overrideComponent(VideoComponent, {
      set: {
        template: `
          <video 
            preload="auto"
            #videoPlayer
            (ended)="videoEnded($event)">
            <source [src]="getVideoSource()" type="video/mp4"/>
          </video>`
      }
    }).createComponent(VideoComponent);
    component = fixture.componentInstance;
    component.src = '';
    component.ended = () => {};
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  afterEach(() => {
    fixture.destroy();
  });

});

请注意,被覆盖的模板中没有'controls'属性。

对单元的逻辑进行单元测试就足够了。

答案 1 :(得分:0)

我们今天在 CI 的 Chrome 版本上遇到了这个问题,但它在开发计算机上运行良好。 我们的解决方案:在我们的 CI 上更新 Chrome(在本例中,从 75 到 91)。