I am trying to create a mock for a function that throws a particular error:
throwCycleDetected(ticket: string): never {
throw new HttpException ()
}
However when I try to mock the function with jest:
throwerGuard.throwCycleDetected = jest
.fn()
.mockImplementation(() => {
throw new Error('Detected a cycle of tickets for ticketId')
})
I get an error:
Type 'Mock<any, any, any>' is not assignable to type '(ticketId: string) => never'. Type 'any' is not assignable to type 'never'.ts(2322)
Can you please help me figure out how am I supposed to mock a function like this without removing the type notation?
I removed the type notation from the function and it allowed the mock to work, but I don't really understand why it is necessary to remove it and I would prefer a solution which allows me to keep the type notation on the function.
never
type is quite tricky when it comes to mocks. I would recommend rather using jest.spyOn
to mock the function.
jest.spyOn(throwerGuard, "throwCycleDetected").mockImplementation(() => {
throw new Error("Detected a cycle of tickets for ticketId");
});
This way you don't interfere with a method via direct assignment and preserve the never
type without any issues.
If you would like to keep the direct assignment, then you'd have to do something like this:
// Using `unknown` as an intermediary type to satisfy TypeScript
throwerGuard.throwCycleDetected = jest.fn().mockImplementation(() => {
throw new Error("Detected a cycle of tickets for ticketId");
}) as unknown as (ticketId: string) => never;
You need to explicitly type the function, but with an intermediary unknown
conversion. Typing as (ticketId: string) => never;
produced another typescript error, which states that any can't be converted to never.