Home > Enterprise >  Test promise inside dynamic import in Angular
Test promise inside dynamic import in Angular

Time:03-30

I have this kind of code:

component.ts

async ngOnInit() {
   import('dom-to-image').then(module => {
      const domToImage = module.default;
      const node = document.getElementById('some-id');
      domToImage.toPng(node).then(dataUrl => {
          // The test is not getting over here
      }).catch(() => {});
   });
}

component.spec.ts

describe('SomeComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
           ....
      }).compileComponents();
      fixture = TestBed.createComponent(SomeComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    })
  )

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

So the question is, How do I mock this promise domToImage.toPng? Is there a solution so the test can continue its execution and resolve the promise?

capture of the coverage

Thanks in advance Isma

CodePudding user response:

You have to mock module.default:

module.default = {
    toPng: () => new Promise((resolve, reject) => {resolve('myExpectedResponseData')})
};

And a mock calling reject in error tests. Note: If you cant mock module.default directly, try spyOnProperty

CodePudding user response:

I remember I had a similar problem and I couldn't spy on the import to mock it.

What I did to make the test happy was I moved it to its own method and I spied on that method.

async ngOnInit() {
   importDomToImage().then(module => {
      const domToImage = module.default;
      const node = document.getElementById('some-id');
      domToImage.toPng(node).then(dataUrl => {
          // The test is not getting over here
      }).catch(() => {});
   });
}

importDomToImage(): Promise<any> { // can make any more specific
  return import('dom-to-image');
}

The first fixture.detectChanges() is when ngOnInit() is called, so we have to mock before that.

describe('SomeComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
           ....
      }).compileComponents();
      fixture = TestBed.createComponent(SomeComponent);
      component = fixture.componentInstance;
      // mock here
      spyOn(component, 'importDomToImage').and.returnValue(Promise.resolve({
        default: {
           toPng: (arg) => Promise.resolve('abc'), // dataUrl will be abc
        }
      }));
      fixture.detectChanges();
    })
  )

  it('should create', async () => {
    // await fixture.whenStable() to resolve all promises
    await fixture.whenStable();
    expect(component).toBeTruthy();
  });
}

The above should hopefully do the trick and get you started.

  • Related