How to mock both static methods and instances in jest with typescript

1.3k views Asked by At

I'm trying to mock both a static method and instances of a class in a jest test with typescript and I am not sure how to get them both mocked. Here's a code example:

record.ts:

export default class Record {
  id: string;

  constructor(id : string) {
    this.id = id;
  }

  getId() : string {
    return this.id;
  }

  static getRecords() : Array<Record> {
    return [new Record('foo'), new Record('bar')]
  }
}

reader.ts:

import Record from './record';

export default class Reader {
  record: Record;
  constructor(record : Record) {
    this.record = record;
  }

  getRecordId() : string {
    return this.record.getId();
  }

  static getReaders() : Array<Reader> {
    return Record.getRecords().map((record) => new Reader(record))
  }
}

reader.test.ts:

import Reader from './reader'
import Record from './record'

jest.mock('./record');
const MockedRecord = Record as jest.Mocked<typeof Record>;
const mockRecord = new MockedRecord('bax');
MockedRecord.getRecords.mockImplementation(() => [mockRecord]);

describe('with getReaders', () => {
  it('returns the id of the associated records', () => {
    mockRecord.getId.mockImplementation(() => 'baz'); // This line fails because "Property 'mockImplementation' does not exist on type '() => string'"
    expect(Reader.getReaders()[0].getRecordId()).toEqual('baz')
  })
})

The problem I'm finding here is that the mockRecord is not mocked, mockRecord.getId is just a normal function not a jest mock function.

Other things I've tried:

  • Explicitly setting the mock as in jest.mock('./record', () => {implementation}), but then I run into typing trouble because the mock loses the static method that's in the signature of Record
  • Using import { mocked } from 'ts-jest/utils'; and const mockRecord = mocked(Record); and then I run into Property 'getId' does not exist on type 'MockedObject<typeof Record>'.

Thank you!

1

There are 1 answers

0
epii On

Oh I finally tried const mockRecord = new MockedRecord('bax') as jest.Mocked<Record>; and it worked!