Jest mock a class instance originally imported from a barrel file

95 Views Asked by At

I am trying to mock a Vuex store imported by an otherwise-vanilla TypeScript class. For the sake of this question, I think it's safe to ignore the Vuex internals and just try to provide an instance of a class with the same name and interface. It may be worth mentioning that, due to some older requirements, I'm using Jest with Babel instead of ts-jest.

In this project, the store(s) are provided by barrel files, which is where I think my issue starts. I want to mock the whole store while ignoring the others which don't come into play. I am able to mock the barrel import and get the the test running with the following:

// ./my-service.ts
import {MyStore} from '../store';

class MyService {
    methodA(item) {
        MyStore.addItemToStore(item);
    }
}
// ../store/__mocks__/my-store.ts
export class MyStoreMock {
    addItemToStore(item) {
        // do stuff
    }
}

export const MyStore = new MyStoreMock();
export default MyStore; // separate line for clarity
// ./my-service.test.ts
import {MyService} from './my-service';

// mock stores imported by barrel file
jest.mock('../store', () => ({
    __esModule: true, // not sure this matters
    MyStore: jest.requireMock('../store/__mocks__/my-store').default,
}));

describe('MyService', () => {
    it('works', () => {
        MyService.methodA({fakeItem});
    });
});

However, TypeScript complains about the mocked MyStore value, "TS2571: Object is of type unknown". I'd like to avoid having to write type definition file(s), and I also just dislike having to use jest.requireMock(...).<export-name>. I just haven't been able to find another way to get this to work.

I have tried variations on the following, with no success.

import {
    MyStoreMock as mockStoreClass,
    MyStore as mockStore
} from '../store/__mocks__/my-store';

jest.mock('../store', () => ({
    __esModule: true,
    // MyStore: jest.fn(() => new mockStoreClass()), // service receives "[Function: mockConstructor]"
    // MyStore: jest.fn(() => mockStore), // service receives "[Function: mockConstructor]"
    // MyStore: mockStore, // TypeError: Cannot read properties of undefined
}));

I'm sure I'm just overlooking something simple (though shenanigans by Vuex or Babel aren't out of consideration). I just need the mockFactory in jest.fn('barrel', () => ({ MyStore: mockFactory })) to be an instance of MyStoreMock, so that the service being tested can call MyStoreMock.addItemToStore.

0

There are 0 best solutions below