1

Here is a fragment from my code in TypeScript:

let myService: MyService;
let myController: MyController;

beforeAll(async function () {
    myService = new MyService(null);
    myController = new MyController(myService);
});

it("should fail due to any 'MyService' error", () => {
    jest.spyOn(myService, 'create').mockImplementation(() => {
        throw new Error(); // ! the test fails here
    });
    expect(myController.create(data)).toThrowError(Error);
});

The create method of MyController is not async, neither is of MyService: both are just regular methods. Now when I try to run this test it fails on the line of the mocked method where the exception is thrown: throw new Error() and it works correctly only if I wrap the create method call with try/catch like this:

try {
    expect(myController.create(data)).toThrowError(Error);
}
catch { }

It looks very strange to me. Shouldn't it work without wrapping in try/catch by design?

Eesa
  • 2,762
  • 2
  • 32
  • 51
Serg
  • 6,742
  • 4
  • 36
  • 54

1 Answers1

2

You just need a small change.


From the .toThrowError doc:

Use .toThrowError to test that a function throws when it is called.


You are passing the result of calling myController.create(data).

You need to pass a function that throws when it is called, in this case:

() => { myController.create(data); }

Change your expect line to this:

expect(() => { myController.create(data); }).toThrowError(Error);  // SUCCESS

...and it should work.

Brian Adams
  • 43,011
  • 9
  • 113
  • 111
  • So, if we pass there an async function that actually means that we pass a `Promise` wrapper which is managed then by Jest and that's why we don't need to wrap it in another function anymore as in this case (with sync method)? – Serg Mar 10 '19 at 09:19
  • @Sergey yes, testing that an `async` function throws an `Error` is really just testing that it returns a `Promise` that rejects with the `Error`. See [this answer](https://stackoverflow.com/a/54585620/10149510) for more details – Brian Adams Mar 11 '19 at 22:01