Mocking a method via jest.spyOn is failing

Viewed 284

I am trying unsuccessfully to mock a Promise:

utils.js

export const fetching = () => {
  const data = [1,2,3];
  return new Promise(resolve=>resolve(data));
}

MyComponent

export function MyComponent() {
  ...
  useEffect(()=>{
    async function callback() {
      const fetchedData = await fetching();
    }
    callback();
  }, []);

  return (
    ...
  );
}

MyTest

import * as myStuff from ...;
jest.spyOn(myStuff, 'fetching').mockImplementation(()=>Promise.resolve([5]))


test('should ...', async () => {
  // given 
  render(<MyComponent/>);
  
});

What am I getting as fetchedData by running the above test is undefined instead of [5]. Any idea why?

1 Answers

You're using the call in useEffect which means it's triggering after the component is actually mounted. Your test is async, but you're not advancing timers. Try:

jest.useFakeTimers()

const fetchSpy = jest.spyOn(myStuff, 'fetching').mockImplementation(()=>Promise.resolve([5]))

test('should ...', async () => {
  // given 
  render(<MyComponent/>);

 // here, we essentially push time forward, after useEffect has been triggered by the mounted component
  act(() => { 
    jest.advanceTimersByTime(1000)
  })

  expect(fetchSpy).toBeCalled()
});
Related