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.