I've put together a pretty basic contact form that works just fine. However I now need to start writing my unit tests and I've run into a load of problems (like I literally have only managed to get a snapshot test to pass so far).
So to start with I'm trying to test that the form should render my validation messages when you click the submit button if you have not filled out all the required sections.
I thought I could achieve this by calling the handleSubmit()
function e.g:
componentRender.find('Formik').instance().props.handleSubmit(badFormValues, { resetForm });
However when I run componentRender.debug()
, my validation messages aren't being rendered. It's like the validationSchema function isn't being called?
Is there something special that needs to be done? I feel like the mapPropsToValues()
function is working, from looking at the state object it's being populated with the values I'm passing the form. I just can't see why validation is seemingly being skipped?
I've been at this for 2 days now and can't find any good examples through google (probably my fault) so any help would be massively appreciated.
For reference here is the test file so far:
And here is my withFormik()
function:
const WrappedFormWithFormik = withFormik({
mapPropsToValues({
companyName,
countryCode,
telNumber,
selectCountry,
postcode,
addressSelect,
siteName,
siteURL,
contactName,
email,
}) {
return {
companyName: companyName || '',
countryCode: countryCode || '',
telNumber: telNumber || '',
selectCountry: selectCountry || '',
postcode: postcode || '',
addressSelect: addressSelect || '',
siteName: siteName || '',
siteURL: siteURL || '',
contactName: contactName || '',
email: email || '',
};
},
validationSchema, // This is a standard Yup.object(), just importing it from a separate file
handleSubmit: (values, { resetForm }) => {
console.log('submitting');
const {
companyName,
countryCode,
telNumber,
selectCountry,
postcode,
addressSelect,
siteName,
siteURL,
contactName,
email,
} = values;
const emailBody = `Name: ${contactName},`
+ `Email: ${email},`
+ `Company Name: ${companyName},`
+ `Country Code: ${countryCode},`
+ `Telephone Number: ${telNumber},`
+ `Country: ${selectCountry},`
+ `Postcode: ${postcode},`
+ `Address: ${addressSelect},`
+ `Website Name: ${siteName},`
+ `Website URL: ${siteURL}`;
// TODO set up actual contact submit logic
window.location.href = `mailto:[email protected]?subject=New partner request&body=${emailBody}`;
resetForm();
},
})(PartnerRegistrationForm);
It might not work if you are trying to submit the form by clicking on a button with type="submit"
I've found the only way to get it to submit (and thus run validations) was by simulating it directly:
const form = wrapper.find('form');
form.simulate('submit', { preventDefault: () => {} });
...and additionally you might need to use something like the following to update the wrapper after formik's async validation and state changes:
setTimeout(() => {
wrapper.update();
}, 0);
Don't forget to use done()
or async await so the test doesn't terminate early.