Karma Jasmin-为什么即使没有测试用例,我的测试用例也会随机失败?

问题描述

这是我的oninit类,不应更改。

  ngOnInit(): void {
        this.setCustomizedValues();
        this.sub = PubSub.subscribe('highlightEntity',(subId,entityIdentifier: string) => {
          document.querySelector(entityIdentifier).classList.add('highlight');
    
          setTimeout(() => {
            document.querySelector(entityIdentifier).classList.remove('highlight');
          },2000);
    
        });
      }

这是最小的测试设置

describe('aComponent',() => {

    
  let httpCallerServiceStub = jasmine.createSpyObj('httpCallerServiceStub',['get']);

  let fixture: ComponentFixture<aComponent>;
  let componentInstance: aComponent;
  localStorage.clear();
  beforeEach(() => {
    Testbed.configureTestingModule({
      declarations: [aComponent],providers: [
        {
          provide: HttpCallerService,useValue: httpCallerServiceStub
        }],imports: [CommonModule,CmcSpinnerModule,NgbModule],}).compileComponents();

    fixture = Testbed.createComponent(aComponent);
    componentInstance = fixture.componentRef.instance;
    fixture.autoDetectChanges();
  });

 describe('ngOnInit method',() => {
    beforeEach(() => {
      fixture.componentInstance.customized = {};
    });

    it('should initialize with minimum input',() => {
      // Triggers ngOnInit
      fixture.detectChanges();
      expect(fixture.componentInstance.customized).toEqual({});
    });
  });

问题是测试随机失败,并显示未找到类列表为null的错误

"message": "An error was thrown in afterall\nTypeError: Cannot read property 'classList' of null\n    at <Jasmine>\n 
   at webpack:///components/path/aComponent.ts:35:53

第35行是oninit函数中的该行

   setTimeout(() => {
                document.querySelector(entityIdentifier).classList.remove('highlight');
              },2000);

这里的问题很少

  1. 我曾尝试将tick(2000)和伪造的asysnc放在ngonit的简单测试中,但仍然给了我相同的随机错误(如this answer所建议)

  2. 我的测试平台配置缺少什么吗?因为即使当我注释掉oninit测试并仅检查一些随机函数(即使没有fixture.detectChanges()),也会发生相同的随机错误

  3. 如果我使用fdescibe运行测试,则每次都会通过所有测试。仅当我从fdescribe中删除f并同时运行其他组件的所有测试时,才会发生此问题。

请指导我,因为过去四天以来我一直在这里停留。

解决方法

要继续进行评论中的讨论,

我建议使用模拟代替实际尝试使aComponent在其他单元测试中起作用。如果它具有自己的依赖关系,则每次使用其他依赖关系或初始化代码扩展它时,都会引发此类错误。而且,如果您不打算在其父组件中测试该功能,那么该模拟就应该这样做。

同时您将摆脱任何滴答声,依此类推...

@Component({
  selector: 'a-component',//make sure the selector is same as in the real component
  template: '<p>Mock A Component</p>'
})
class MockAComponent {}

beforeEach(() => {
  TestBed.configureTestingModule({
      declarations: [
        ParentComponent,MockAComponent,],// ...
  });
});

或者一个简单的解决方案是安装ng-mocks,然后您无需单独创建它。

beforeEach(() => {
  TestBed.configureTestingModule({
      declarations: [
        ParentComponent,MockComponent(AComponent),// ...
  });
});

有关此的更多信息,请访问:Mocking Child Components - Angular 2