How to write test cases for Subscriber and timeout inside ngOnit method?

醉酒当歌 提交于 2020-12-27 06:15:37

问题


I have a class in angular8 application with following ngOnit method

  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);

    });
  }

I have initialised the following test case

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({});
    });
  });

So when I run this it randomly throwing the following error

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

Here is console error in karma test runner,

and here is what the file suggest

So after this point however number of test I write ahead, the issue still remains the same, sometime it works, sometime it doesnt.

Can you please tell me what to do with pubsub.subscriber and timeout inside ngonit?


回答1:


Since you're messing with the DOM, ngOnInit can be too early for that. The DOM has not yet been painted. Try moving the logic to ngAfterViewInit

ngAfterViewInit() {
    this.sub = PubSub.subscribe('highlightEntity', (subId, entityIdentifier: string) => {
      document.querySelector(entityIdentifier).classList.add('highlight');

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

And to test the setTimeout, you can use fakeAsync and tick.

import { fakeAsync, tick } from '@angular/core/testing';
...
it('should initialize with minimum input', fakeAsync(() => {
      // Triggers ngOnInit
      fixture.detectChanges();
      // do your assertions for ngAfterViewInit
      // make 2s pass in a fake way
      tick(2000);
      // do your assertions for the setTimeout callback
      expect(fixture.componentInstance.customized).toEqual({});
    }));


来源:https://stackoverflow.com/questions/64242278/how-to-write-test-cases-for-subscriber-and-timeout-inside-ngonit-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!