-2

I am trying to test a react component by mocking the function used to get data from an external api, that is called from within the useEffect hook. However I am getting the following error

Cannot read properties of undefined (reading 'then') TypeError: Cannot read properties of undefined (reading 'then')

I have tried separating the function definition from with useEffect to improve testability but could do with some pointers.

Following advice I tried to separate the fetching of the data and the component to improve testability.

Examples of the dataFetching and the component that is tested are included below:

The definition for the data fetching is:

// api.ts

import {EmployeeModel} from "../models/EmployeeModel";

export async function getAllEmployees(): Promise<EmployeeModel[]> {
    const baseUrl: string = "http://localhost:8080/employees";
    const response: Response = await fetch(baseUrl);
    const responseJson = await response.json();
    const employees: EmployeeModel[] = [];

    for (let key in responseJson) {

        const emp: EmployeeModel = new EmployeeModel(
            responseJson[key].name,
            responseJson[key].gender,
            responseJson[key].address,
            responseJson[key].postcode,
            responseJson[key].department,
            responseJson[key].salary,
            responseJson[key].email,
            responseJson[key].employeeNumber
        );

        employees.push(emp);
    }
    return employees;
}

The component that is tested:


// React component

import React, {useEffect, useState} from "react";
import {JSX} from "react";
import {EmployeeTable} from "./EmployeeTable";
import {EmployeeModel} from "../models/EmployeeModel";
import {getAllEmployees} from "../services/EmployeeApiService";
import {Simulate} from "react-dom/test-utils";
import {EmployeeDataTransferModel} from "../models/EmployeeDataTransferModel";

export const EmployeeTableWrapper: React.FC<{}> = (props): JSX.Element => {

    const [employees, setEmployees] = useState<EmployeeModel[]>([]);

    useEffect((): void => {

        getAllEmployees()
            .then((response: EmployeeModel[]): void => {
                setEmployees(response)
            })
            .catch((error: any) => {
        });
       // setIsLoading(false);

    }, [getAllEmployees])

    return (
        <EmployeeTable employees={employees}/>
    )
}

And the test that was created:

Finally the test that has been written so far (I have removed the asserts until the I can get the test passing):

`import React from 'react';
import {render, screen} from '@testing-library/react';
import {EmployeeTableWrapper} from "../../components/EmployeeTableWrapper";
import {getAllEmployees} from "../../services/EmployeeApiService";
import {EmployeeModel} from "../../models/EmployeeModel";


const mockEmployees: EmployeeModel[] = [
    new EmployeeModel(
        "Test_User",
        "M",
        "3 Fake Street",
        "M1",
        5,
        "Tech",
        23000.0,
        "test2test.com")
]

jest.mock("../../services/EmployeeApiService", () => ({
    getAllEmployees: jest.fn(() => Promise.resolve(mockEmployees))
}));


describe("EmployeeTableWrapper", () => {
    it('should ', async function () {

       await act(async() => {
            render(<EmployeeTableWrapper />)

            await getAllEmployees();
        })

    });
});`

Any advice would be greatly appreciated.

Lint
  • 1
  • 1

1 Answers1

0

It looks like you just did the wrong just.mock for getAllEmployees. It is outside of the test and therefore not visible in your test. Move it to your test and check test again:

describe("EmployeeTableWrapper", () => {
  it("should ", async function () {
    jest.mock("../../services/EmployeeApiService", () => ({
      getAllEmployees: jest.fn(() => Promise.resolve(mockEmployees)),
    }));
    
    await act(async () => {
      render(<EmployeeTableWrapper />);

      await getAllEmployees();
    });
  });
});
BuGaGa
  • 302
  • 2
  • 9