How to fire an event React Testing Library

3.1k Views Asked by At

I have some code, in a hook, to detect whether the browser is online / offline:

export function useConnectivity() {
  const [isOnline, setNetwork] = useState(window.navigator.onLine);
  const updateNetwork = () => {
    setNetwork(window.navigator.onLine);
  };
  useEffect(() => {
    window.addEventListener('offline', updateNetwork);
    window.addEventListener('online', updateNetwork);
    return () => {
      window.removeEventListener('offline', updateNetwork);
      window.removeEventListener('online', updateNetwork);
    };
  });
  return isOnline;
}

I have this basic test:

test('hook should detect offline state', () => {
  let internetState = jest.spyOn(window.navigator, 'onLine', 'get');
  internetState.mockReturnValue(false);

  const { result } = renderHook(() => useConnectivity());
  expect(result.current.valueOf()).toBe(false);
});

However, I want to run a test to see whether it returns the correct value when an offline event is triggered, not just after the mocking of the returned value on render. What is the best way to approach this? Where I have got so far is this:

test('hook should detect offline state then online state', async () => {
  const { result, waitForNextUpdate } = renderHook(() => useConnectivity());

  act(() => {
    const goOffline = new window.Event('offline');
    window.dispatchEvent(goOffline);
  });

  await waitForNextUpdate();
  
  expect(result.current).toBe(false);
});
1

There are 1 best solutions below

0
On BEST ANSWER

I'm not sure about 'best', but this is one way: change the mock response halfway through the test, and tweak some of the async code:

test('hook should detect online state then offline state', async () => {
  const onLineSpy = jest.spyOn(window.navigator, 'onLine', 'get');

  // Pretend we're initially online:
  onLineSpy.mockReturnValue(true);

  const { result, waitForNextUpdate } = renderHook(() => useConnectivity());

  await act(async () => {
    const goOffline = new window.Event('offline');

    // Pretend we're offline:
    onLineSpy.mockReturnValue(false);

    window.dispatchEvent(goOffline);

    await waitForNextUpdate();
  });

  expect(result.current).toBe(false);
});