Home > Back-end >  useCallback function is not a function while using unit test Jest
useCallback function is not a function while using unit test Jest

Time:10-13

This is my test code snippet but it throws an exception, TypeError: componentInstance.loadLoanApplication is not a function :

it('should render the SubmittedLoan', () => {
    const loanData = {
      data: {
        id: 1,
    };

    const div = document.createElement('div');
    const wrapper = mount(
      <AppProviders>
        <MemoryRouter initialEntries={['/review/153']}>
          <SubmittedLoan
            match={{ params: { loanId: 1, step: 1 } }}
            history={{
              location: { state: { from: 'register' } },
              push() {},
            }}
          />
        </MemoryRouter>
      </AppProviders>,
      div,
    );

    const componentInstance = wrapper
      .find(SubmittedLoan)
      .children()
      .first()
      .children()
      .first()
      .instance();
    const loanApplication = {
      id: 1,
      steps_data: [
        { slug: 'step_1', title: 'Step 1' },
        { slug: 'step_2', title: 'Step 2' },
      ],
      status: ApiCaptiq.STATUS_SUBMITTED,
    };

    expect(wrapper.find(SubmittedLoan).length).toBe(1);
    componentInstance.loadLoanApplication(1, 1);
    componentInstance.onLoadLoanApplication(loanData);
    componentInstance.onLoadFail();
    componentInstance.setState({
      formData: [{ item: 'value' }, { item2: 'value2' }],
      activeStep: 1,
      loanApplication,
    });

    componentInstance.handleSnackbarClose(new Event('click'), '');

    componentInstance.setState({ activeStep: 3 });
  });

Then my Component which uses memo is as follows :


export const SubmittedLoan = memo(() => {
  const [loanApplication, setLoanApplication] = useState<LoanApplication | null>(null);
  const [message, setMessage] = useState({
    message: '',
    open: false,
    messageType: '',
  });
  const authContext = useContext(AuthContext);
  const customerContext = useCustomerData();
  const params = useParams();
  const history = useHistory();
  const classes = useStyles();
  const { loanId } = params;

  const onl oadFail = useCallback(() => {
    setMessage({
      message: 'Die verfügbaren Darlehensarten können nicht aufgelistet werden',
      open: true,
      messageType: 'error',
    });
  }, []);

  const onl oadLoanApplication = useCallback(
    (response: AxiosResponse) => {
      setTemplateSettings(response, authContext);
      if (
        response.data.status === ApiCaptiq.STATUS_STARTING ||
        response.data.status === ApiCaptiq.STATUS_IN_PROGRESS ||
        response.data.status === ApiCaptiq.STATUS_PRE_WAITING
      ) {
        history.push(`/view/${loanId}`);
      } else {
        setLoanApplication(response.data);
      }
    },
    [loanId, authContext, history],
  );

  const loadLoanApplication = useCallback(
    async (loan_id: number) => {
      try {
        const response = await request.get(`${ApiCaptiq.LOAN_APPLICATION_URL}${loan_id}/`);
        const { fetchCustomerProfile } = customerContext;
        await fetchCustomerProfile(response.data.customer_profile_id);
        onLoadLoanApplication(response);
      } catch (err) {
        onLoadFail();
      }
    },
    [customerContext, onl oadLoanApplication, onl oadFail],
  );
  ...

What could be the possible reason for this

CodePudding user response:

The functions you are defining inside the component, are not just available on the component instance. In fact, there is not way to call them. You can test only by mocking the fetch calls they are doing.

If you really need callable functions in your component (you should try to avoid these..), you could use this: https://reactjs.org/docs/hooks-reference.html#useimperativehandle

Perhaps better would be to extract this data loading logic elsewhere and test it separately.

  • Related