Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow partial TypeScript types when mocking functions - Jest, TypeScript

I have a function which I would like to mock for testing purposes in TypeScript. In my tests, all I care about are the json and the status. However, when using Jest's jest.spyOn the type of my mocked function is set to return a http Response type. This is awkward as it means I have to manually go and implement a bunch of functions and properties that are irrelevant and arbitrary.

I suspect there is some way to use a partial type here to allow better and more useful mocking by overriding the return type to only that I care about. How would I go about doing this?

export function mockApi(json: object, status: number): void {
  jest.spyOn(
    myApiModule,
    'methodWhichReturnsAResponse'
  ).mockImplementation(() =>
    Promise.resolve({
      json: () => Promise.resolve(json),
      status,
      // Below here is to appease jest types (not needed for
      // testing purposes at the time of writing)
      headers: {
        has: (name: string) => true,
        // get, set, etc...
      },
      ok: true,
      redirected: false,
      // and about 10 other properties which exist on the Response type
      // ...
    }),
  );
}

like image 322
James Mulholland Avatar asked Oct 28 '22 14:10

James Mulholland


1 Answers

You can use as...

export function mockApi(json: object, status: number): void {
  jest.spyOn(
    myApiModule,
    'methodWhichReturnsAResponse'
  ).mockImplementation(() =>
    Promise.resolve({
      json: () => Promise.resolve(json),
      status
    } as http.Response), // <-- here
  );
}

The as keyword, used for typecasting, when used to convert a literal to type X, will allow you to define it only partially, but you still have type-checking because you cannot define props that don't exist.

Example:

type X {
  a: number
  b: number
}

const x = { a: 2 } as X // OK
const y = { a: 3, c: 2 } as X // NOT OK, because c does not exist in X
like image 109
André Pena Avatar answered Nov 09 '22 10:11

André Pena