Jest spyOn not working with typescript: "Property 'mockRestore' is missing in type 'Spy'"

11,708

Short Answer

The global spyOn(...) function returns a jasmine.Spy not a jest.SpyInstance. The reason for this, as far as I can tell, is to ease migration from Jasmine to Jest.

Here are two options:

let barSpy: jest.SpyInstance;
barSpy = jest.spyOn(a, 'bar'); // <--- explicitly use jest.spyOn

// or

let barSpy: jasmine.Spy; // <--- use jasmine.Spy as your type
barSpy = spyOn(a, 'bar');

Further Explanation

The node_modules\@types\jest\index.d.ts file has the Jest type definitions. By looking at them, we can see the two implementations of spyOn.

  • The spyOn that returns a jest.SpyInstance is inside the jest namespace.
  • The spyOn that returns a jasmine.Spy is in the global namespace.

Unless you're in the process of migrating from Jasmine to Jest, I would use the jest.spyOn function instead of the global one.

Share:
11,708
jjbskir
Author by

jjbskir

The best way through it is through it.

Updated on June 16, 2022

Comments

  • jjbskir
    jjbskir almost 2 years

    When using spyOn with jest and typescript I am getting this type error:

    Type 'Spy' is not assignable to type 'SpyInstance<{}>'. Property 'mockRestore' is missing in type 'Spy'.

    Here is a code example that causes it:

    class A {
      foo = () => this.bar() + 1;
      bar = () => 1;
    }
    
    test('should pass', () => {
      const a = new A();
      let barSpy: jest.SpyInstance;
      barSpy = spyOn(a, 'bar');
      a.foo();
      expect(barSpy).toHaveBeenCalled();
    });
    

    When I run this example the test passes, but the typescript complier fails.