I have a situation where I'm trying to test the code path when a promise rejects. The setup is relatively complicated but I've reduced it down to what is a minimum reproducible example:
let resolver;
let rejecter;
const p = new Promise((resolve, reject) => {
resolver = resolve;
rejecter = reject;
});
const f = jest.fn((x) => {
console.log(x);
});
const run = () => {
return p
.then(() => {
f("resolved");
})
.catch(() => {
f("rejected");
});
};
beforeEach(() => {
f.mockClear();
});
// this test passes
test("it should call with resolved when p resolves", async () => {
run();
resolver();
await p;
expect(f).toHaveBeenCalledWith("resolved");
});
// this test fails
test("it should call with rejected when p rejects", async () => {
run();
rejecter();
await p;
expect(f).toHaveBeenCalledWith("rejected");
});
My problem is that, despite the fact that f is indeed called with "rejected", the test fails, with the reason
thrown: undefined
My guess at this point is that it has something to do with the fact the promise is rejecting; I had hoped this wouldn't be an issue as it's caught. How can I have this test complete sucessfully?
I fixed this by adding a catch onto the promise p:
// this test fails
test("it should call with rejected when p rejects", async () => {
run();
rejecter();
await p.catch(() => {});
expect(f).toHaveBeenCalledWith("rejected");
});