Search code examples
typescriptunit-testingjestjsts-jest

ts-jest: Import MockedObject type


How do I import the type MockedObject into my test file? My code example is as below

import { mocked, MockedObject } from 'ts-jest/utils';
import someFunction from '../src/common/someFunction';
import SomeClass from '../src/model/SomeClass';
import SomeInterface from '../src/interface/SomeInterface';

jest.mock('../src/model/SomeClass');

describe('run test', () => {
  let mockValidators: any;
  beforeAll(async () => {
    mockedValidators = (await someFunction()).map((v: SomeInterface) =>
      mocked(v)
    ):
  }
})

I tried to import MockedObject from ts-jest/utils but VSCode cannot find it. I want to replace any with MockedObject<SomeInterface>.

Error:

Module '"../../../node_modules/ts-jest/utils"' has no exported member 'MockedObject'.


Solution

  • From the source code, we can see ts-jest/utils does NOT export MockedObject type. You can copy the types from ts-jest/dist/util/testing.d.ts file, add them to your project.

    E.g.

    index.test.ts:

    import { mocked } from 'ts-jest/utils';
    
    interface SomeInterface {
      validate(): boolean;
    }
    declare type MockableFunction = (...args: any[]) => any;
    declare type MethodKeysOf<T> = {
      [K in keyof T]: T[K] extends MockableFunction ? K : never;
    }[keyof T];
    declare type PropertyKeysOf<T> = {
      [K in keyof T]: T[K] extends MockableFunction ? never : K;
    }[keyof T];
    declare type ArgumentsOf<T> = T extends (...args: infer A) => any ? A : never;
    declare type ConstructorArgumentsOf<T> = T extends new (...args: infer A) => any ? A : never;
    interface MockWithArgs<T extends MockableFunction> extends jest.MockInstance<ReturnType<T>, ArgumentsOf<T>> {
      new (...args: ConstructorArgumentsOf<T>): T;
      (...args: ArgumentsOf<T>): ReturnType<T>;
    }
    declare type MaybeMockedConstructor<T> = T extends new (...args: any[]) => infer R ? jest.MockInstance<R, ConstructorArgumentsOf<T>> : {};
    declare type MockedFunction<T extends MockableFunction> = MockWithArgs<T> &
      {
        [K in keyof T]: T[K];
      };
    declare type MockedObject<T> = MaybeMockedConstructor<T> &
      {
        [K in MethodKeysOf<T>]: T[K] extends MockableFunction ? MockedFunction<T[K]> : T[K];
      } &
      {
        [K in PropertyKeysOf<T>]: T[K];
      };
    
    const UserValidator: SomeInterface = {
      validate: () => true,
    };
    
    async function someFunction() {
      return [UserValidator];
    }
    
    describe('run test', () => {
      let mockedValidators: Array<MockedObject<SomeInterface>>;
      beforeAll(async () => {
        mockedValidators = (await someFunction()).map((v: SomeInterface) => mocked(v));
      });
    });