使用笑话和酶进行测试时,Formik 不会更新错误
我有一个 Formik 注册表单,已通过 yup 验证。当验证架构未满足时,我想显示错误组件。一切都在浏览器中运行,但是当我进行测试时,即使应该已经存在错误,并且酶的行为就像没有错误一样。有人可以告诉我我做错了什么吗?这很奇怪,因为当我将 console.log(errors.email) 放入 Formik 的返回函数中时,我看到“它似乎不是有效的电子邮件地址”。我的测试控制台中出现错误。另一方面,当我将 erros.email 放入 Formik 的返回函数中时,在测试中它看起来不存在。
// SignUp.tsx
const SignUp: React.FC = () => {
const { register, errorMessage } = React.useContext(AuthContext);
const initialValues = {
email: '',
password: '',
passwordRepeat: '',
};
const hasErrors = (errors: FormikErrors<typeof initialValues>) => {
return Object.keys(errors).length !== 0 || errorMessage;
};
const allFieldsWereTouched = (touched: FormikTouched<typeof initialValues>) => {
return Array.from(Object.values(touched)).filter((wasTouched) => wasTouched).length === Object.keys(initialValues).length;
};
const signUpValidationSchema = Yup.object().shape({
email: Yup.string().email('It does not seem to be a valid email address.'),
password: Yup.string().min(5, 'Password must have at least 5 characters.').max(15, 'Password must not have more than 15 characters.'),
passwordRepeat: Yup.string().oneOf([Yup.ref('password')], 'Both passwords must be equal.'),
});
const submitForm = (values: typeof initialValues) => {
register(values.email, values.password);
};
return (
<AuthWrapper>
<h3 className={classes.authModalTitle} data-test='signup-modal-title'>
Sign Up
</h3>
<Formik initialValues={initialValues} onSubmit={submitForm} validationSchema={signUpValidationSchema}>
{({ errors, touched }) => {
return (
<Form>
<FormikTextInput type='email' name='email' description='E-mail address' as={Input} />
<FormikTextInput type='password' name='password' description='Password' as={Input} />
<FormikTextInput type='password' name='passwordRepeat' description='Password repeat' as={Input} />
{errors.email && <Error message={errors.email || errors.password || errors.passwordRepeat || errorMessage} />}
<Button className={classes.buttonAdditional} type='submit' dataTest='signup-button'>
Open account
</Button>
</Form>
);
}}
</Formik>
<FormInfo question='Already have an account?' answer='Sign in' path='SignIn' />
</AuthWrapper>
);
};
export default SignUp;
// SignUp.test.tsx
const setup = () => {
return mount(
<MemoryRouter>
<AuthContextProvider>
<SignUp />
</AuthContextProvider>
</MemoryRouter>
);
};
describe('<SignUp />', () => {
let wrapper: ReactWrapper;
beforeEach(() => {
wrapper = setup();
});
afterEach(() => {
wrapper.unmount();
});
describe('showing errors', () => {
const simulateTyping = async (name: string, value: string | number) => {
const formField = formikFindByInputName(wrapper, name);
formField.simulate('change', { target: { name, value } });
formField.simulate('blur');
};
const checkErrorExistance = (wrapper: ReactWrapper, condition: boolean) => {
const error = findByTestAttr(wrapper, 'error');
expect(error.exists()).toBe(condition);
};
it('does not show error when email input value is wrong but not all inputs were touched', () => {
simulateTyping('email', 'test');
checkErrorExistance(wrapper, true);
});
});
});
I have a Formik signup form that is validated with yup. When validation schema isn't fulfilled i want to show error component. Everything works in browser, but when i do my tests, even though there should be errors already jest and enzyme behaves like there was no error. Can someone tell me what am I doing wrong? It's strange because when I put console.log(errors.email) in Formik's return function i see that there is 'It does not seem to be a valid email address.' error in my test console. From the other hand when i put erros.email in Formik's return function, in test it looks like it doesn't exist.
// SignUp.tsx
const SignUp: React.FC = () => {
const { register, errorMessage } = React.useContext(AuthContext);
const initialValues = {
email: '',
password: '',
passwordRepeat: '',
};
const hasErrors = (errors: FormikErrors<typeof initialValues>) => {
return Object.keys(errors).length !== 0 || errorMessage;
};
const allFieldsWereTouched = (touched: FormikTouched<typeof initialValues>) => {
return Array.from(Object.values(touched)).filter((wasTouched) => wasTouched).length === Object.keys(initialValues).length;
};
const signUpValidationSchema = Yup.object().shape({
email: Yup.string().email('It does not seem to be a valid email address.'),
password: Yup.string().min(5, 'Password must have at least 5 characters.').max(15, 'Password must not have more than 15 characters.'),
passwordRepeat: Yup.string().oneOf([Yup.ref('password')], 'Both passwords must be equal.'),
});
const submitForm = (values: typeof initialValues) => {
register(values.email, values.password);
};
return (
<AuthWrapper>
<h3 className={classes.authModalTitle} data-test='signup-modal-title'>
Sign Up
</h3>
<Formik initialValues={initialValues} onSubmit={submitForm} validationSchema={signUpValidationSchema}>
{({ errors, touched }) => {
return (
<Form>
<FormikTextInput type='email' name='email' description='E-mail address' as={Input} />
<FormikTextInput type='password' name='password' description='Password' as={Input} />
<FormikTextInput type='password' name='passwordRepeat' description='Password repeat' as={Input} />
{errors.email && <Error message={errors.email || errors.password || errors.passwordRepeat || errorMessage} />}
<Button className={classes.buttonAdditional} type='submit' dataTest='signup-button'>
Open account
</Button>
</Form>
);
}}
</Formik>
<FormInfo question='Already have an account?' answer='Sign in' path='SignIn' />
</AuthWrapper>
);
};
export default SignUp;
// SignUp.test.tsx
const setup = () => {
return mount(
<MemoryRouter>
<AuthContextProvider>
<SignUp />
</AuthContextProvider>
</MemoryRouter>
);
};
describe('<SignUp />', () => {
let wrapper: ReactWrapper;
beforeEach(() => {
wrapper = setup();
});
afterEach(() => {
wrapper.unmount();
});
describe('showing errors', () => {
const simulateTyping = async (name: string, value: string | number) => {
const formField = formikFindByInputName(wrapper, name);
formField.simulate('change', { target: { name, value } });
formField.simulate('blur');
};
const checkErrorExistance = (wrapper: ReactWrapper, condition: boolean) => {
const error = findByTestAttr(wrapper, 'error');
expect(error.exists()).toBe(condition);
};
it('does not show error when email input value is wrong but not all inputs were touched', () => {
simulateTyping('email', 'test');
checkErrorExistance(wrapper, true);
});
});
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我遇到了同样的问题,必须自己运行
validateForm
,所以类似:然后检查
newErrors
。I had the same issue and had to run
validateForm
myself, so something like:Then check the
newErrors
.