Man*_*han 4 unit-testing reactjs material-ui
我刚刚将我的 React 项目升级到 MUI V5,其中 KeyboardDatePicker 组件已根据 MUI 文档迁移到 DatePicker。由于某种原因,React 库测试无法触发日期选择器组件的模拟处理函数。
\n我的组件
\nimport React from "react"\nimport AdapterDateFns from '@mui/lab/AdapterDateFns';\nimport moment from "moment"\nimport LocalizationProvider from '@mui/lab/LocalizationProvider';\nimport DatePicker from '@mui/lab/DatePicker';\nimport { TextField } from "@mui/material"\n// Required for Material UI datepicker since it is timezone sensitive\nexport const formatDate = date =>\n date ? new Date(moment(date).year(), moment(date).month(), moment(date).date()) : null\n\nexport default function IndependentDateRangePicker({\n handleStartDateChange,\n handleEndDateChange,\n startDateValue,\n endDateValue,\n disableDate\n}) {\n return (\n <LocalizationProvider dateAdapter={AdapterDateFns}>\n <DatePicker\n inputFormat="MM/dd/yyyy"\n aria-label="change start date" \n disabled={disableDate}\n value={formatDate(startDateValue)}\n onChange={handleStartDateChange}\n maxDate={endDateValue ? formatDate(endDateValue) : ""}\n InputProps={{ "data-testid": "start-date-picker" }}\n renderInput={(props) => <TextField {...props} label="Start Date" variant="standard"/>}\n />\n <DatePicker\n style={{ marginTop: 5 }}\n inputFormat="MM/dd/yyyy"\n aria-label="change start date"\n disabled={disableDate}\n value={formatDate(endDateValue)}\n onChange={handleEndDateChange}\n minDate={startDateValue ? formatDate(startDateValue) : ""}\n InputProps={{ "data-testid": "end-date-picker" }}\n renderInput={(props) => <TextField {...props} variant="standard" label="End Date" />}\n />\n </LocalizationProvider>\n )\n}\nRun Code Online (Sandbox Code Playgroud)\n我的反应测试文件
\nimport React from "react"\nimport { render, fireEvent } from "@testing-library/react"\nimport IndependentDateRangePicker, { formatDate } from "../components/IndependentDateRangePicker"\n\ndescribe("<IndependentDateRangePicker />", () => {\n let c, handleEndDateChangeMock, handleStartDateChangeMock\n\n beforeEach(() => {\n handleEndDateChangeMock = jest.fn()\n handleStartDateChangeMock = jest.fn()\n })\n \n\n\n describe("When no dates are passed as props", () => {\n beforeEach(() => {\n c = render(\n <IndependentDateRangePicker\n handleStartDateChange={handleStartDateChangeMock}\n handleEndDateChange={handleEndDateChangeMock}\n startDateValue={""}\n endDateValue={""}\n />\n )\n })\n\n it("should not call handlers when dates are empty", () => {\n fireEvent.change(c.getByTestId("start-date-picker").querySelector('input'), {\n target: { value: "" }\n })\n fireEvent.change(c.getByTestId("end-date-picker").querySelector('input'), {\n target: { value: "" }\n })\n expect(handleStartDateChangeMock).not.toHaveBeenCalled()\n expect(handleEndDateChangeMock).not.toHaveBeenCalled()\n })\n\n it("should call handler when start date is updated", async () => {\n fireEvent.change(c.getByTestId("start-date-picker").querySelector('input'), {\n target: { value: "01/03/2000" }\n })\n expect(handleStartDateChangeMock).toHaveBeenCalledWith(expect.any(Date), "01/03/2000")\n })\n\n it("should call handler when end date is updated", () => {\n fireEvent.change(c.getByTestId("end-date-picker").querySelector('input'), {\n target: { value: "01/04/2000" }\n })\n expect(handleEndDateChangeMock).toHaveBeenCalledWith(expect.any(Date), "01/04/2000")\n })\n })\n\n})\nRun Code Online (Sandbox Code Playgroud)\n测试错误信息
\n \xe2\x97\x8f <IndependentDateRangePicker /> \xe2\x80\xba When no dates are passed as props \xe2\x80\xba should call handler when end date is updated\n\n expect(jest.fn()).toHaveBeenCalledWith(...expected)\n\n Expected: Any<Date>, "01/04/2000"\n\n Number of calls: 0\n\n 55 | target: { value: "01/04/2000" }\n 56 | })\n > 57 | expect(handleEndDateChangeMock).toHaveBeenCalledWith(expect.any(Date), "01/04/2000")\n | ^\n 58 | })\n 59 | })\n 60 |\n\n at Object.<anonymous> (src/__tests__/IndependentDateRangePicker.test.js:57:36)\nRun Code Online (Sandbox Code Playgroud)\n您可以看到触发handleEndDateChangeMock函数时存在一些问题。
\n请在这件事上给予我帮助。TIA。
\n小智 9
问题是 DatePicker 在测试中默认为移动模式,您应该在测试之前添加以下代码,它们就会通过:
beforeAll(() => {
// add window.matchMedia
// this is necessary for the date picker to be rendered in desktop mode.
// if this is not provided, the mobile mode is rendered, which might lead to unexpected behavior
Object.defineProperty(window, "matchMedia", {
writable: true,
value: (query) => ({
media: query,
// this is the media query that @material-ui/pickers uses to determine if a device is a desktop device
matches: query === "(pointer: fine)",
onchange: () => {},
addEventListener: () => {},
removeEventListener: () => {},
addListener: () => {},
removeListener: () => {},
dispatchEvent: () => false,
}),
});
}
afterAll(() => {
delete window.matchMedia;
});
Run Code Online (Sandbox Code Playgroud)
来源: https: //github.com/mui-org/material-ui-pickers/issues/2073
| 归档时间: |
|
| 查看次数: |
6051 次 |
| 最近记录: |