I enabled async validation for a field in my redux form. I use jest and enzyme to test form submission.
I tried mocking the async validation function with a simple resolved promise, the form still can not be submitted. But I removed async validation, the form can be submitted without any problems.
...
jest.mock('../../../../../../utilities/validators');
it('should set registration info and set current step with correct values when registration form is successfully submitted', () => {
const store = createStore(
combineReducers({
form: formReducer,
}),
);
validateEmailUnique.mockImplementation(() => Promise.resolve());
const mockOnSetRegistrationInfo = jest.fn();
const mockOnSetRegistrationCurrentStep = jest.fn();
const updatedProps = {
...defaultProps,
onSetRegistrationInfo: mockOnSetRegistrationInfo,
onSetRegistrationCurrentStep: mockOnSetRegistrationCurrentStep,
};
const wrapper = mount(
<Provider store={store}>
<StepOne {...updatedProps} />
</Provider>,
);
const form = wrapper.find('form');
const businessEmailTextField = wrapper.find(
'input#business-email-text-field',
);
businessEmailTextField.simulate('change', {
target: {
value: '[email protected]',
},
});
form.simulate('submit');
expect(mockOnSetRegistrationInfo).toHaveBeenCalled();
I expect the form to be submitted and then the 'onSetRegistrationInfo' function which is inside the form submitted callback function to be called. However, since the async validation is not passed, the form can not be submitted during test.
The issue is that the async validation hasn't completed by the time the expect
runs and fails.
From what I can see of your code it doesn't look like you have direct access to the Promise
from your async validation step so you won't be able to await
it directly...
...but if you've mocked any async
operations to resolve immediately then they should all complete in one cycle of the Promise
microtask queue.
If that is the case then you can move your assertions to something like setImmediate
or setTimeout
and use done
to let Jest
know when the test is complete:
it('should set registration info...', done => { // <= use done
// ...
form.simulate('submit');
setImmediate(() => {
expect(mockOnSetRegistrationInfo).toHaveBeenCalled(); // Success!
done(); // <= now call done
});
});