Jacek Krajewski
Jacek Krajewski

Reputation: 83

An update inside a test was not wrapped in act(...) error

I have a problem while testing with jest and enzyme. When I try to test changes in one of my Formik's inputs I get this error that an update inside a test was not wrapped in act(...). I tried to import act and wrap line of code that simulates changing input (as shown below) but it didn't help. So here is my question how and where should i use this act to stop getting this warning in my test?

// SignInModal

const SignInModal = () => {
  const { isLoading } = useSelector((state) => state.auth);
  const { props } = useSelector((state) => state.modals);
  const { submit } = props;

  const signInForm = (
    <React.Fragment>
      <div className={classes.logoContainer}>
        <Logo />
      </div>
      <h3 className={classes.title}>Log in to Friends</h3>
      <div className={classes.formContainer} data-test={'component-sign-in-modal'}>
        <Formik
          initialValues={{ email: '', password: '' }}
          onSubmit={(values) => {
            submit({ ...values });
          }}
        >
          {() => {
            return (
              <Form>
                <div className={classes.inputsContainer}>
                  <MyFormikInput as={Input} required name='email' type='email' placeholder='Email address' className={classes.input} />
                  <MyFormikInput as={Input} required name='password' type='password' placeholder='Password' className={classes.input} />
                </div>
                <Button className={classes.button} isTransparent>
                  Sign in
                </Button>
              </Form>
            );
          }}
        </Formik>
      </div>
    </React.Fragment>
  );

  return <div className={classnames(classes.modal, classes.modalVisible)}>{isLoading ? <Spinner /> : signInForm}</div>;
};

// MyFormikInput

const MyFormikInput = ({ label, ...props }) => {
  const [field] = useField(props);

  return (
    <div className={classnames(classes.container, props.className)}>
      <Field {...field} {...props} />
    </div>
  );
};

export default MyFormikInput;

// Input

const Input = (props) => {
  const { type, name, onChange, value, required, className, disabled, placeholder } = props;
  return (
    <input
      type={type}
      name={name}
      onChange={onChange}
      value={value}
      required={required}
      className={classnames(className, classes.input)}
      disabled={disabled}
      placeholder={placeholder}
      autoComplete='off'
    ></input>
  );
};

export default Input;

// SignInModal.test

import { act } from '@testing-library/react';

let store;

const setup = (initialState) => {
  store = storeFactory(initialState);
  return mount(
    <Provider store={store}>
      <SignInModal />
    </Provider>
  );
};

describe('sign in inputs typing', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = setup();
  });

  afterEach(() => {
    // wrapper.unmount();
  });
  test('changes email input content on change', () => {
    const emailInput = formikFindByInputName(wrapper, 'email');
    act(() => {
      emailInput.simulate('change', { target: { name: 'email', value: '[email protected]' } });
    });
    expect(emailInput.instance().value).toEqual('[email protected]');
  });
});

Upvotes: 1

Views: 3614

Answers (1)

Jacek Krajewski
Jacek Krajewski

Reputation: 83

UPDATE

Actually i found a way to get rid of this warning by doing it like this:

test('changes email input content on change', async () => {
    const emailInput = formikFindByInputName(wrapper, 'email');
    await act(async () => {
      await emailInput.simulate('change', { target: { name: 'email', value: '[email protected]' } });
    });
    expect(emailInput.instance().value).toEqual('[email protected]');
  });

But I still want to ask if there is a better way to fix my problem?

Upvotes: 4

Related Questions