How to spy on Vue composable inner function that is called inside another function inside composable?

The project is using Vue, Vitest and Vue Test Utils. I am new to UI unit testing and I need to test that when one function from composable is called, then the other function should have been called.

My functions look something like this (details omitted):


export function useHelper() {

  async function wait(milliseconds: number): Promise<void> {
    return await new Promise<void>(resolve => setTimeout(() => resolve(), milliseconds));
  }

  async function executeInBatches(delay = 0) {
    if (delay) {
      await wait(delay);
    }
  }

return {
    executeInBatches,
    wait,
  };
}


My unit test is next:


beforeEach(() => {
  vi.useFakeTimers({shouldAdvanceTime: true});
});

afterEach(() => {
  vi.useRealTimers();
  vi.clearAllMocks();
});


 it('should call function wait when delay is provided', async () => {
      const composable = useHelper();
      const waitSpy = vi.spyOn(composable, 'wait');
      const delay = 100;

      await executeInBatches(delay);
      vi.advanceTimersByTime(delay * 2);

      expect(waitSpy).toHaveBeenCalled();
    });

I do not understand why waitSpy does not work. If i do exactly same thing, but spy on window.setTimeout, which is called inside wait function, then the timeout spy correctly works.

Working example with spying on setTimeout:


 it('should call setTimeout when delay is provided', async () => {
      const composable = useHelper();
      const timeoutSpy = vi.spyOn(window 'setTimeout')
      const delay = 100;

      await executeInBatches(delay);
      vi.advanceTimersByTime(delay * 2);

      expect(timeoutSpy).toHaveBeenCalled();
    });

Could you please help, why does spying on composable does not work?

Thanks in advance