Search code examples
javascriptasynchronouskarma-jasmine

How can I catch an asynchronously thrown error in Karma/Jasmine


My code does complicated stuff with promises and observables. When an error is thrown at a certain place, i can not catch it in my tests.

I tried various variants, but i am not able to catch it:

const getPromise = () =>
  new Promise((resolve) => {
    setTimeout(() => {
      throw new Error("a!");
    });
  });

fit("use toThrow", async () => {
  expect(await getPromise()).toThrow();
});
// Error: oh! thrown

fit("use expectAsync", async () => {
  await expectAsync(getPromise()).toBeRejectedWithError();
});
// Error: oh! thrown

fit("use done", async (done) => {
  try {
    await getPromise();
  } catch (e) {
    expect(e).toEqual("a!");
  }
  done();
});
// Error: oh! thrown

fit("use fakeAsync", fakeAsync(() => {
  expectAsync(getPromise()).toBeRejectedWithError();
}));
// Error: 1 timer(s) still in the queue.

Please not that getPromise should be actually my code under test. That setTimout and being moved to another call stack is the actual problem is an assumption. There is no setTimout in my code but various rxjs stuff, which might have a setTimeout internally.

My test-framework is karma/jasmine.

I already read:


Solution

  • The Answer, I found, is ugly enough. I hope something better exists:

    fit('use onerror', done => {
      window.onerror = message => {
        expect(message).toEqual('Uncaught Error: oh!');
        window.onerror = null;
        done();
      };
      getPromise().finally(() => { window.onerror = null; }).then(done);
    });