1

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);
  });
});

1 Answer 1

2

For anyone else having a similar issue I discovered the problem. In my global test config I had mockReset: true. This was clearing all mocks before each test and resetting them back to an empty function, hence why the initial mocks were not working. Once this setting was removed the tests work as expected.

1
  • Thanks for this, rather than remove it I set restoreMocks: true which reverts to initial implementation
    – MintWelsh
    Commented Apr 21 at 22:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.