Reputation: 51
I just upgraded my React project to MUI V5 where the KeyboardDatePicker component has been migrated to DatePicker as per the MUI docs. For some reason the React Library test is not able to trigger the mock handler function of the date picker component.
My Component
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>
)
}
My React Test file
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")
})
})
})
Test Error Message
● <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)
you can see there is some problem in triggering the handleEndDateChangeMock function.
Please help me with this. TIA.
Upvotes: 5
Views: 7075
Reputation: 21
I was struggling with a similiar issue, with the newer version of DatePicker from the @mui/x-date-pickers/DatePicker package, i was using the component as following:
<DatePicker
label={'Date of birth'}
value={dateOfBirth}
openTo="year"
views={['year', 'month', 'day']}
onChange={setDateOfBirth}
disableFuture
desktopModeMediaQuery={theme.breakpoints.up('sm')}
renderInput={params => (
<TextField
{...params}
sx={{
width: '100%',
}}
/>
)}
name="dateOfBirth"
/>
so i made a little change to the previous answer and added this to my test:
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 === '(min-width:600px)',
onchange: () => {},
addEventListener: () => {},
removeEventListener: () => {},
addListener: () => {},
removeListener: () => {},
dispatchEvent: () => false,
}),
})
})
afterAll(() => {
delete window.matchMedia
})
This solved the problem.
You can checkout a full reproducible example here https://codesandbox.io/s/datepicker-usjhlm?file=/src/index.test.js:1847-2634
Upvotes: 1
Reputation: 101
The problem is the DatePicker is defaulting to mobile mode in tests, you should add the following code before your tests and they will pass:
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;
});
Source : https://github.com/mui-org/material-ui-pickers/issues/2073
Upvotes: 10