首页 > 解决方案 > 如何在启用异步验证的情况下测试 redux 表单

问题描述

我为我的 redux 表单中的一个字段启用了异步验证。我使用 jest 和酵素来测试表单提交。

我尝试用一​​个简单的已解决承诺模拟异步验证功能,但仍然无法提交表单。但是我删除了异步验证,表单可以毫无问题地提交。

...
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: 'business@email.com',
      },
    });

    form.simulate('submit');

    expect(mockOnSetRegistrationInfo).toHaveBeenCalled();

我希望提交表单,然后调用表单提交回调函数内部的“onSetRegistrationInfo”函数。但是,由于异步验证没有通过,所以在测试期间无法提交表单。

标签: reactjsjestjsenzymeredux-form

解决方案


expect问题是异步验证在运行和失败时尚未完成。

从我所看到的代码来看,您似乎无法Promise从异步验证步骤直接访问,因此您将无法直接访问await它...

...但是如果您模拟了任何async要立即解决的操作,那么它们应该都在Promise微任务队列的一个周期内完成。

如果是这种情况,那么您可以将您的断言移动到类似setImmediateorsetTimeout并用于doneJest知道测试何时完成:

it('should set registration info...', done => {  // <= use done

  // ...

  form.simulate('submit');

  setImmediate(() => {
    expect(mockOnSetRegistrationInfo).toHaveBeenCalled();  // Success!
    done();  // <= now call done
  });
});

推荐阅读