【问题标题】:MUI V5 React unit test not triggering the Date Picker handlerMUI V5 React 单元测试未触发日期选择器处理程序
【发布时间】:2021-10-14 18:53:58
【问题描述】:

我刚刚将我的 React 项目升级到 MUI V5,其中 KeyboardDatePicker 组件已根据 MUI 文档迁移到 DatePicker。由于某种原因,React 库测试无法触发日期选择器组件的模拟处理函数。

我的组件

import React from "react"
import AdapterDateFns from '@mui/lab/AdapterDateFns';
import moment from "moment"
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import DatePicker from '@mui/lab/DatePicker';
import { TextField } from "@mui/material"
// Required for Material UI datepicker since it is timezone sensitive
export const formatDate = date =>
    date ? new Date(moment(date).year(), moment(date).month(), moment(date).date()) : null

export default function IndependentDateRangePicker({
    handleStartDateChange,
    handleEndDateChange,
    startDateValue,
    endDateValue,
    disableDate
}) {
    return (
        <LocalizationProvider dateAdapter={AdapterDateFns}>
            <DatePicker
                inputFormat="MM/dd/yyyy"
                aria-label="change start date" 
                disabled={disableDate}
                value={formatDate(startDateValue)}
                onChange={handleStartDateChange}
                maxDate={endDateValue ? formatDate(endDateValue) : ""}
                InputProps={{ "data-testid": "start-date-picker" }}
                renderInput={(props) => <TextField  {...props} label="Start Date" variant="standard"/>}
            />
            <DatePicker
                style={{ marginTop: 5 }}
                inputFormat="MM/dd/yyyy"
                aria-label="change start date"
                disabled={disableDate}
                value={formatDate(endDateValue)}
                onChange={handleEndDateChange}
                minDate={startDateValue ? formatDate(startDateValue) : ""}
                InputProps={{ "data-testid": "end-date-picker" }}
                renderInput={(props) => <TextField {...props} variant="standard" label="End Date" />}
            />
        </LocalizationProvider>
    )
}

我的 React 测试文件

import React from "react"
import { render, fireEvent } from "@testing-library/react"
import IndependentDateRangePicker, { formatDate } from "../components/IndependentDateRangePicker"

describe("<IndependentDateRangePicker />", () => {
    let c, handleEndDateChangeMock, handleStartDateChangeMock

    beforeEach(() => {
        handleEndDateChangeMock = jest.fn()
        handleStartDateChangeMock = jest.fn()
    })
    


    describe("When no dates are passed as props", () => {
        beforeEach(() => {
            c = render(
                <IndependentDateRangePicker
                    handleStartDateChange={handleStartDateChangeMock}
                    handleEndDateChange={handleEndDateChangeMock}
                    startDateValue={""}
                    endDateValue={""}
                />
            )
        })

        it("should not call handlers when dates are empty", () => {
            fireEvent.change(c.getByTestId("start-date-picker").querySelector('input'), {
                target: { value: "" }
            })
            fireEvent.change(c.getByTestId("end-date-picker").querySelector('input'), {
                target: { value: "" }
            })
            expect(handleStartDateChangeMock).not.toHaveBeenCalled()
            expect(handleEndDateChangeMock).not.toHaveBeenCalled()
        })

        it("should call handler when start date is updated", async () => {
            fireEvent.change(c.getByTestId("start-date-picker").querySelector('input'), {
                target: { value: "01/03/2000" }
            })
            expect(handleStartDateChangeMock).toHaveBeenCalledWith(expect.any(Date), "01/03/2000")
        })

        it("should call handler when end date is updated", () => {
            fireEvent.change(c.getByTestId("end-date-picker").querySelector('input'), {
                target: { value: "01/04/2000" }
            })
            expect(handleEndDateChangeMock).toHaveBeenCalledWith(expect.any(Date), "01/04/2000")
        })
    })

})

测试错误信息

 ● <IndependentDateRangePicker /> › When no dates are passed as props › should call handler when end date is updated

    expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: Any<Date>, "01/04/2000"

    Number of calls: 0

      55 |              target: { value: "01/04/2000" }
      56 |          })
    > 57 |          expect(handleEndDateChangeMock).toHaveBeenCalledWith(expect.any(Date), "01/04/2000")
         |                                          ^
      58 |      })
      59 |  })
      60 |

      at Object.<anonymous> (src/__tests__/IndependentDateRangePicker.test.js:57:36)

你可以看到触发handleEndDateChangeMock函数有一些问题。

请帮我解决这个问题。 TIA。

【问题讨论】:

    标签: reactjs unit-testing material-ui


    【解决方案1】:

    问题是 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;
    });
    

    来源:https://github.com/mui-org/material-ui-pickers/issues/2073

    【讨论】:

    • 我对此进行了测试,它可以工作。感谢你的回答。这应该被标记为正确答案。
    猜你喜欢
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2022-08-03
    相关资源
    最近更新 更多