我在尝试测试在 React 组件中声明的函数时遇到了麻烦。在我的例子中,我调用了这些函数handleChange
,changeCapacity
它们被Form.control
元素使用,它是一个 Select。
我写了一个应该使用这些选择的测试,所以我认为我也在测试它们关联的函数,但显然我不是因为我的 Coverage 文件状态没有测试这些函数。
这是我正在测试的组件,
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;
这是我在这个组件上运行的测试:
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));
});
});