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.