【发布时间】:2021-04-07 13:55:29
【问题描述】:
我有一个只有一个文本字段的简单表单。我使用 react material ui 库和 formik 进行验证和验证。我无法通过使用浅酶法获得表单中的文本字段。不知道我做错了什么。
declarationForm.js
import React, { useState, useEffect } from 'react';
import * as Yup from 'yup';
import { Formik } from 'formik';
import { useNavigate, Prompt } from "react-router-dom";
import { Box, Button, Card, CardContent, CardHeader, Divider, Grid, TextField } from '@material-ui/core';
import { get_declarations_details, put_declarations_details } from './../../utils/service';
const DeclarationsForm = () => {
const [ initialData, setInitialData ] = useState({ declarations:'' });
useEffect(()=>{
get_data();
},[]);
let navigate = useNavigate();
const get_data = async() =>{
try {
const result = await get_declarations_details();
if(result){
setInitialData({
...initialData,
...result,
});
}
} catch (error) {
console.log(error);
}
}
const put_data = async(data) =>{
try {
const result = await put_declarations_details(data);
if(result){
setInitialData({
...initialData,
...result,
});
}
} catch (error) {
console.log(error);
}
}
return (
<Formik
initialValues={initialData}
enableReinitialize={true}
validationSchema={
Yup.object().shape({
declarations: Yup.string().max(255).required('Declarations is required'),
})
}
onSubmit={(values) => {
if(JSON.stringify(initialData) !== JSON.stringify(values)){
put_data(values);
}
navigate(`/summary`, { replace: true })
}}
>
{({
errors,
handleBlur,
handleChange,
handleSubmit,
isSubmitting,
touched,
isValid,
values
}) => (
<form onSubmit={handleSubmit}>
<Card>
<Prompt
when={!isValid}
message="Are you sure you want to proceed without saving?"
/>
<CardHeader
subheader="The information can be edited"
title="Declarations"
/>
<Divider />
<CardContent>
<Grid
container
spacing={3}
>
<Grid
item
md={6}
xs={12}
>
<TextField
fullWidth
error={Boolean(touched.declarations && errors.declarations)}
helperText={touched.declarations && errors.declarations}
label="Declarations"
name="declarations"
handleBlur={handleBlur}
onChange={handleChange}
required
value={values.declarations}
variant="outlined"
/>
</Grid>
</Grid>
</CardContent>
<Divider />
<Box
display="flex"
justifyContent="flex-end"
p={2}
>
<Button
color="primary"
variant="contained"
disabled={isSubmitting}
onClick={handleSubmit}
>
Continue
</Button>
</Box>
</Card>
</form>
)}
</Formik>
);
};
export default DeclarationsForm;
我的测试文件如下
declarationForm.test.js
import { createShallow } from '@material-ui/core/test-utils';
import React from 'react';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import DeclarationsForm from './declarationsForm';
import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles';
import { TextField } from '@material-ui/core';
configure({ adapter: new Adapter() });
describe('<DeclarationsForm />', () => {
let shallow, wrapper;
beforeAll(() => { // This is Mocha; in Jest, use beforeAll
shallow = createShallow();
});
beforeEach(() => {
wrapper = shallow(<MuiThemeProvider><DeclarationsForm /></MuiThemeProvider>);
});
it('should work', () => {
console.log(wrapper.find(TextField).debug());
expect(wrapper.find(TextField)).toHaveLength(1);
});
});
当我运行下面的测试是结果
FAIL src/views/declarations/declarationsForm.test.js
● Console
console.error node_modules/prop-types/checkPropTypes.js:20
Warning: Failed prop type: The prop `theme` is marked as required in `ThemeProvider`, but its value is `undefined`.
in ThemeProvider (at declarationsForm.test.js:19)
console.log src/views/declarations/declarationsForm.test.js:23
● <DeclarationsForm /> › should work
expect(received).toHaveLength(expected)
Expected length: 1
Received length: 0
Received object: {}
22 |
23 | console.log(wrapper.find(TextField).debug());
> 24 | expect(wrapper.find(TextField)).toHaveLength(1);
| ^
25 | });
26 | });
at Object.<anonymous> (src/views/declarations/declarationsForm.test.js:24:37)
wrapper is unable to find text field or form.
How to debug this? What is the right approach to write test when we have also used useNavigate method within the component?
【问题讨论】:
-
看起来您可能需要在测试中将
theme属性传递给MuiThemeProvider。我很久以前就放弃了 Enzyme,但也许如果你做了一个完整的mount与shallow,我认为shallow安装对子组件的处理方式不同,并且不会完全渲染它们。
标签: reactjs jestjs material-ui enzyme formik