测试内的更新未包含在 act(...) 错误中

发布于 2025-01-10 08:34:16 字数 3424 浏览 0 评论 0原文

我在用笑话和酶进行测试时遇到问题。当我尝试测试 Formik 输入之一的更改时,我收到此错误,表明测试内的更新未包含在 act(...) 中。我尝试导入 act 并换行模拟更改输入的代码(如下所示),但没有帮助。所以这是我的问题,我应该如何以及在哪里使用此行为来停止在测试中收到此警告?

// 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]');
  });
});

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]');
  });
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温暖的光 2025-01-17 08:34:16

更新

实际上我找到了一种方法来通过这样做来摆脱这个警告:

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]');
  });

但我仍然想问是否有更好的方法来解决我的问题?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文