skip to Main Content

I’m trying to test a custom hook, that fetches some token from the API.
The ../api is my own module. Both files are in the same directory

// useTokenHook.tsx
import { getToken } from '../api';

const someVariable = useSelector();
useEffect(() => {
  const asyncWrapper = async () => {
    const token = await getToken()
    // do some stuff with token
  }
  asyncWrapper();
}, [someVariable]);

I’m trying to test it using jest and RTL

// useTokenHook.test.tsx
const getTokenMock = jest.fn();

jest.mock('../api', () => ({
  getToken: () => getTokenMock,
}));

describe('x', () => {
  it('should work', () => {
    renderHook(() => { useTokenHook(); },{ wrapper });

    expect(getTokenMock).toBeCalledTimes(1);
  });
});

I get the error:

    Expected number of calls: 1
    Received number of calls: 0

Without the mock, I can see that the original getToken method gets called. I would assume the mock should also be called, but at least jest doesn’t say so.
I tried adding async to it() callback but the result is the same

2

Answers


  1. Chosen as BEST ANSWER

    Based on RAllen answer I came up with the following:

    // useTokenHook.test.tsx
    import * as api from '../api';
    
    jest.mock("../api");
    
    describe('x', () => {
      it('should work', () => {
        const getTokenSpy = jest.spyOn(api, 'getToken')
    
        renderHook(() => { useTokenHook(); },{ wrapper });
    
        expect(getTokenSpy).toBeCalledTimes(1);
      });
    });
    

    Which solves my problem


  2. Try to use the following approach. Notice that there is no wrapper around getToken call. The code is obviously not tested but the concept should work.

    // useTokenHook.tsx
    import { getToken } from '../api';
    
    const someVariable = useSelector();
    useEffect(async () => {
        const token = await getToken()
        // do some stuff with token
    }, [someVariable]);
    

    And then the test:

    // useTokenHook.test.tsx
    import * as api from '../api';
    
    jest.mock("../api");
    api.getToken = jest.fn().mockImplementation(() => {
     return "the token";
    });
    
    describe('x', () => {
      it('should work', () => {
        renderHook(() => { useTokenHook(); },{ wrapper });
    
        expect(api.getToken).toBeCalledTimes(1);
      });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search