I'm having trouble trying to test functions declared inside a React component.
In my case i have these functions called handleChange
and changeCapacity
, they're used by the Form.control
element, it's a Select.
I wrote a test that should use these Selects, so i thought i was also testing the functions they are associated with, but apparently i'm not since my Coverage file state that the functions are not tested.
This is the Component i'm testing,
const TableFilter: React.FC<TableFilterProps> = ({ handleTables }) => {
const tables: TableI[] = useSelector(tablesSelector);
const filteredTables: TableI[] = useSelector(filteredTablesSelector);
const prevCapacity: number = useSelector(capacitySelector);
const prevLocation: string = useSelector(locationSelector);
const dispatch = useDispatch();
const locations: string[] = tables.map(
(table: { location: string }) => table.location
);
const capacity: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const uniqueLocations = [...new Set(locations)];
const handleChange = (event: { target: { value: any } }) => {
let locationFilter = event.target.value;
dispatch(storeLocation(locationFilter));
if (filteredTables && prevCapacity) {
const available = tables.filter(
(table: { location: string; capacity: number }) =>
table.location === locationFilter && table.capacity >= prevCapacity
);
available.length === 0
? handleTables()
: dispatch(filterTables(available));
} else {
const filteredArr = tables.filter(
(table: { location: string }) => table.location === locationFilter
);
dispatch(filterTables(filteredArr));
}
};
const changeCapacity = (event: { target: { value: any } }) => {
let capacityFilter = event.target.value;
dispatch(storeCapacity(capacityFilter));
if (filteredTables && prevLocation) {
const available = tables.filter(
(table: { capacity: number; location: string }) =>
table.capacity >= capacityFilter && table.location === prevLocation
);
available.length === 0
? handleTables()
: dispatch(filterTables(available));
} else {
const filteredArr = tables.filter(
(table: { capacity: number }) => table.capacity >= capacityFilter
);
dispatch(filterTables(filteredArr));
}
};
return (
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Select a table</Form.Label>
<Form.Control
onChange={handleChange}
as="select"
aria-label="form-select-location"
>
<option>Select your table's location</option>
{uniqueLocations &&
uniqueLocations.map((location: string, index: number) => (
<option aria-label="location" key={index} value={location}>
{location}
</option>
))}
</Form.Control>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Select the capacity of your table</Form.Label>
<Form.Control
onChange={changeCapacity}
as="select"
aria-label="form-select-capacity"
>
<option>Number of persons sitting </option>
{capacity &&
capacity.map((capacity: number, index: number) => (
<option aria-label="capacity" key={index} value={capacity}>
{capacity}
</option>
))}
</Form.Control>
</Form.Group>
</Form>
);
};
export default TableFilter;
this is the test i'm running on this Component:
describe("TableFilter", () => {
const filteredTablesSelectorSpy = jest.spyOn(
actions,
"filteredTablesSelector"
);
const tablesSelectorSpy = jest.spyOn(actions, "tablesSelector");
const capacitySelectorSpy = jest.spyOn(actions, "capacitySelector");
const locationSelectorSpy = jest.spyOn(actions, "locationSelector");
beforeEach(() => {
filteredTablesSelectorSpy.mockReset().mockReturnValue([]);
tablesSelectorSpy.mockReset().mockReturnValue([]);
capacitySelectorSpy.mockReset().mockReturnValue(0);
locationSelectorSpy.mockReset().mockReturnValue("");
});
test("testing Capacity and Location Selects, should find the Table with the values selected", () => {
render(<TableFilter handleTables={() => {}} />);
const capacitySelect = screen.getByLabelText("form-select-capacity");
const locationSelect = screen.getByLabelText("form-select-location");
expect(capacitySelect).toBeInTheDocument();
expect(locationSelect).toBeInTheDocument();
waitFor(() =>
user.selectOptions(
capacitySelect,
within(capacitySelect).getByRole("option", { name: "8" })
)
);
waitFor(() =>
user.selectOptions(
locationSelect,
within(locationSelect).getByRole("option", { name: "Patio" })
)
);
waitFor(() =>
expect(screen.getByRole("option", { name: "8" })).toBeInTheDocument()
);
waitFor(() =>
expect(screen.getByRole("option", { name: "Patio" })).toBeInTheDocument()
);
waitFor(() => expect(filteredTablesSelectorSpy).toHaveBeenCalledTimes(2));
waitFor(() => expect(tablesSelectorSpy).toHaveBeenCalledTimes(1));
waitFor(() => expect(capacitySelectorSpy).toHaveBeenCalledTimes(2));
waitFor(() => expect(locationSelectorSpy).toHaveBeenCalledTimes(2));
});
});