Using vi.mock
to create a factory of mocked named exports, if i provide an initial mock implementation to a named export it does not work. Instead, I have to manually set a mock implementation in every test. According to Vitest docs I should be able to set an initial mock implementation or return value in the factory and it should be used in the test. but this isn't working in my case. Is there something I am doing wrong or missing?
// bar.ts - this is the module to be mocked
export function barFn() {
return {
bar: 2,
};
}
// foo.ts - this is the module under test
import { barFn } from './bar';
export function fooFn() {
const { bar } = barFn();
return bar;
}
// test.test.ts - this is what i would EXPECT to pass the test
// However the test fails: TypeError: Cannot destructure property 'bar' of 'barFn(...)' as it is undefined.
import { fooFn } from './foo';
vi.mock('./bar', () => ({
barFn: vi.fn(() => ({ bar: 3 })),
}));
// FAILS
describe('test', () => {
it('should return mocked bar', () => {
const actual = fooFn();
expect(actual).toBe(3);
});
});
// test.test.ts - this is the only way i an get the mock to pass - if I specifically
// define a mockReturnValue in the test
import { barFn } from './bar';
import { fooFn } from './foo';
vi.mock('./bar', () => ({
barFn: vi.fn(),
}));
// PASSES
describe.only('test', () => {
it('should return mocked bar', () => {
barFn.mockReturnValue({ bar: 3 });
const actual = fooFn();
expect(actual).toBe(3);
});
});
// test.test.ts - this also passes but then barFn is not a mock so i cannot change its
// implementation per test
import { barFn } from './bar';
import { fooFn } from './foo';
vi.mock('./bar', () => ({
barFn: () => ({ bar: 3 }),
}));
describe.only('test', () => {
// PASSES
it('should return mocked bar', () => {
const actual = fooFn();
expect(actual).toBe(3);
});
// FAILS - barFn is not a mock
it('should also return mocked bar', () => {
// TypeError: barFn.mockReturnValue is not a function
barFn.mockReturnValue({ bar: 4 });
const actual = fooFn();
expect(actual).toBe(4);
});
});