0

I would like to do validation onBlur. But when I am testing it in jest, the error message will not show up in first onblur in first test clause. However, it shows up in second onblur in second test clause.

Here I show the DOM from first and second clause and we can see the error message shows up in 2nd clause after second onblur.

How to make the error message showing up in the first onblur in first test clause?

React File

import React from 'react';
import { useForm } from 'react-hook-form';
import { string, object } from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';

interface TestingProps {
  fullname: string;
}

const TestingPage: React.FC = () => {
  const schema = object().shape({
    fullname: string().required('fullname is required!')
  });

  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<TestingProps>({
    resolver: yupResolver(schema),
    mode: 'onBlur'
  });

  const submit = () => {};

  return (
    <div>
      <form onSubmit={handleSubmit(submit)}>
        <input className="testing" {...register('fullname')} />
      </form>
      {errors?.fullname && <p>{errors.fullname.message}</p>}
      <input type="submit" />
    </div>
  );
};
export default TestingPage;

Jest Test File

import Enzyme, { mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import TestingPage from './TermsAndConditions';

Enzyme.configure({ adapter: new Adapter() });

describe('Testing page test', () => {
  let wrapper: any;

  test('first attempt to show error message onblur', () => {
    wrapper = mount(<TestingPage />);
    wrapper.find('.testing').simulate('focus');
    wrapper.find('.testing').simulate('blur');
    console.log(wrapper.debug());
  });

  test('second attempt to show error message onblur', () => {
    wrapper.find('.testing').simulate('blur');
    console.log(wrapper.debug());
  });
});

screenshot of DOM

LY Hooi
  • 165
  • 1
  • 9

1 Answers1

1

You just need to await before test assertion, because react-hook-form validation and submit are async. Use flush-promises e.g.

function flushPromises() {
    return new Promise(resolve => setImmediate(resolve));
}

  test('first attempt to show error message onblur', async () => {
    wrapper = mount(<TestingPage />);
    wrapper.find('.testing').simulate('focus');
    wrapper.find('.testing').simulate('blur');
    await flushPromises();
    console.log(wrapper.debug());
  });
  • Thanks for the direction! Though I still cannot get the update with your answer, I found the solution with following codes on this [link](https://stackoverflow.com/a/51045733/10514268) maybe due to my jest version 27 `await new Promise(process.nextTick); wrapper.update(); console.log(wrapper.debug()); ` – LY Hooi Jul 08 '22 at 12:57