await expect(svc.charge(order)).rejects.toThrow(PaymentError)"await expect(svc.charge(order)).rejects.toThrow(PaymentError)" is correct. .rejects unwraps the rejected promise, and await makes the test wait for the check.
An async function never throws synchronously. It returns a rejected promise instead. So "expect(() => svc.charge(order)).toThrow(PaymentError)" sees no throw and fails.
"expect(svc.charge(order)).rejects.toThrow(PaymentError) with no await or return" is wrong because the test ends before the assertion runs. .rejects must be awaited or returned.
"await expect(svc.charge(order)).toThrow(PaymentError)" is wrong because toThrow needs a function, not a promise. Without .rejects, the await does not help.
Read more