reactjstypescriptreact-hooksjestjsmocking

How to Mock a Custom Hook Used Within Another Hook in Jest?


I am trying to test a custom hook useCopySystem, which internally uses another custom hook useBackdrop. I want to mock the behavior of useBackdrop within pasteCopiedDay during its execution to prevent it from failing. The useBackdrop hook depends on the user being online, but I just want to set its value to true directly so that it returns specific values during my tests.

const createTestStore = () =>
  configureStore({
    reducer: {
      auth: authReducer,
      global: globalReducer,
      misc: miscReducer,
    },
  });

const testStore = createTestStore();

// Wrapper
const wrapper = ({ children }: { children: ReactNode }) => <Provider store={testStore}>{children}</Provider>;



describe('test copy system', () => {
  
  // Render the pasteCopiedDay hook 
  const {
    result: {
      current: { pasteCopiedDay },
    },
  } = renderHook(() => useCopySystem(), { wrapper });

// Mock the internal custom hook (must return true in order to the fn to continue 
  // This mock is not affecting pasteCopiedDay
  jest.mock('../utilities/useBackdrop', () => ({
    __esModule: true,
    useBackdrop: jest.fn(() => ({
      showBackdrop: jest.fn(() => true),
    })),
  }));

  it('pasteCopiedDay', async () => {
    await pasteCopiedDay('day3Id', mockedCopyDayType);
    })


Solution

  • Mock the useBackdrop before importing the useCopySystem, so that when useCopySystem is imported, it uses the mocked version of useBackdrop.

    beforeEach(() => {
      jest.resetAllMocks();
    });
    
    // Mock useBackdrop before importing useCopySystem
    jest.mock('../utilities/useBackdrop', () => ({
      __esModule: true,
      useBackdrop: jest.fn(() => ({
        showBackdrop: jest.fn(() => true),
      })),
    }));
    
    // Wrapper
    const createTestStore = () =>
      configureStore({
        reducer: {
          auth: authReducer,
          global: globalReducer,
          misc: miscReducer,
        },
      });
    
    const testStore = createTestStore();
    
    const wrapper = ({ children }: { children: ReactNode }) => <Provider store={testStore}>{children}</Provider>;
    
    describe('test copy system', () => {
      // Render the pasteCopiedDay hook
      const {
        result: {
          current: { pasteCopiedDay },
        },
      } = renderHook(() => useCopySystem(), { wrapper });
    
      it('pasteCopiedDay', async () => {
        await pasteCopiedDay('day3Id', mockedCopyDayType);
      });
    });