'How do you use a jest mock in a typed test fake in typescript?

I have an interface that defines that objects implementing it should have certain functions. For example:

interface MyInterface {
    someFunc: () => void,
    /* ... other bits and bobs */
}

and I want to write a test that one of these functions is called in certain conditions.

I have a test using test fakes that looks something like this:

const obj: MyInterface = {
    ...fakeObj,
    someFunc: jest.fn(() => {})
};

/* ... the actual test code */

expect(obj.someFunc.mock.calls.length).toBe(1);

This was working before I gave an explicit type to the obj variable. However, now it produces the error:

Property 'mock' does not exist on type '() => void'.

I wanted to add types to my objects because I wanted to be able to use refactoring tools without having to manually fix all my tests.

How can I write a test that a function is called on an object when using explicit types?



Solution 1:[1]

The easiest way is to use the mocked test helper.

The mocked test helper provides typings on your mocked modules and even their deep methods, based on the typing of its source. It make use of the latest TypeScript features so you even have argument types completion in the IDE (as opposed to jest.MockInstance).

E.g.

index.ts:

export interface MyInterface {
  someFunc: () => void;
}

export function main(obj: MyInterface) {
  return obj.someFunc();
}

index.test.ts:

import { main, MyInterface } from './';
import { mocked } from 'ts-jest/utils';

describe('63478184', () => {
  it('should pass', () => {
    const obj: MyInterface = {
      someFunc: jest.fn().mockReturnValueOnce('mocked value'),
    };
    main(obj);
    expect(mocked(obj.someFunc).mock.calls.length).toBe(1);
  });
});

unit test result with coverage report:

 PASS  src/stackoverflow/63478184/index.test.ts (12.902s)
  63478184
    ? should pass (8ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.759s

source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/63478184

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zwessels