React测试库表单提交事件与真实浏览器不同

React testing library form submit event is different from the real browser

所以我正在尝试测试一个在 React 中实现的表单。当我通过 jest 提交表单时,我得到的事件与通过浏览器提交事件时不同。

我用的测试是这个:

it("shows success message if registering was successful", async () => {
        fetchMock.mockReturnValueOnce(Promise.resolve(new Response("", { status: 200 })));

        const wrapper = render(<Provider store={getStore()}>
            <RegisterComponent/>
        </Provider>);
        const emailTextfield = wrapper.getByPlaceholderText(/email@domain.de/i);
        const password = wrapper.getByPlaceholderText(/eingeben/i);
        const firstName = wrapper.getByPlaceholderText(/max/i);
        const lastName = wrapper.getByPlaceholderText(/mustermann/i);
        const retryPassword = wrapper.getByPlaceholderText(/wiederholen/i);
        const privacyPolicy = wrapper.getByRole("checkbox");
        const registerButton = wrapper.getByRole("button");
        fireEvent.change(emailTextfield, { target: { value: "test@test.de" } });
        fireEvent.change(password, { target: { value: "Test1234!" } });
        fireEvent.change(retryPassword, { target: { value: "Test1234!" } });
        fireEvent.change(firstName, { target: { value: "Lukas" } });
        fireEvent.change(lastName, { target: { value: "Germerott" } });
        fireEvent.change(privacyPolicy, { target: { checked: true } });
        fireEvent.click(registerButton);
        const successMessage = await wrapper.findByText(/erfolgreich/i);

        expect(successMessage).toBeTruthy();
    });

所以我正在为所有输入安装组件和触发事件。记录的事件是这个:

<ref *1> HTMLFormElement {
      '__reactFiber$sikt1ggzmx': <ref *2> FiberNode {
        tag: 5,
        key: null,
        elementType: 'form',
        type: 'form',
        stateNode: [Circular *1],
        return: FiberNode {
          tag: 0,
          key: null,
          elementType: [Function: RegisterComponent],
          type: [Function: RegisterComponent],
          stateNode: null,
          return: [FiberNode],
          child: [Circular *2],
          sibling: null,
          index: 0,
          ref: null,
          pendingProps: {},
          memoizedProps: {},
          updateQueue: [Object],
          memoizedState: [Object],
          dependencies: [Object],
          mode: 0,
          flags: 0,
          nextEffect: null,
          firstEffect: null,
          lastEffect: null,
          lanes: 0,
          childLanes: 0,
          alternate: [FiberNode],
          actualDuration: 0,
          actualStartTime: -1,
          selfBaseDuration: 0,
          treeBaseDuration: 0,
          _debugID: 10780,
          _debugSource: [Object],
          _debugOwner: null,
          _debugNeedsRemount: false,
          _debugHookTypes: [Array]
        },
        child: FiberNode {
          tag: 11,
          key: null,
          elementType: [Object],
          type: [Object],
          stateNode: null,
          return: [Circular *2],
          child: [FiberNode],
          sibling: null,
          index: 0,
          ref: null,
          pendingProps: [Object],
          memoizedProps: [Object],
          updateQueue: [Object],
          memoizedState: [Object],
          dependencies: [Object],
          mode: 0,
          flags: 0,
          nextEffect: null,
          firstEffect: null,
          lastEffect: null,
          lanes: 0,
          childLanes: 0,
          alternate: [FiberNode],
          actualDuration: 0,
          actualStartTime: -1,
          selfBaseDuration: 0,
          treeBaseDuration: 0,
          _debugID: 10784,
          _debugSource: [Object],
          _debugOwner: [FiberNode],
          _debugNeedsRemount: false,
          _debugHookTypes: [Array]
        },
        sibling: null,
        index: 0,
        ref: null,
        pendingProps: {
          onSubmit: [Function: submit],
          'data-testid': 'formular',
          children: [Object]
        },
        memoizedProps: {
          onSubmit: [Function: submit],
          'data-testid': 'formular',
          children: [Object]
        },
        updateQueue: null,
        memoizedState: null,
        dependencies: null,
        mode: 0,
        flags: 0,
        nextEffect: null,
        firstEffect: null,
        lastEffect: null,
        lanes: 0,
        childLanes: 0,
        alternate: FiberNode {
          tag: 5,
          key: null,
          elementType: 'form',
          type: 'form',
          stateNode: [Circular *1],
          return: [FiberNode],
          child: [FiberNode],
          sibling: null,
          index: 0,
          ref: null,
          pendingProps: [Object],
          memoizedProps: [Object],
          updateQueue: null,
          memoizedState: null,
          dependencies: null,
          mode: 0,
          flags: 0,
          nextEffect: null,
          firstEffect: [FiberNode],
          lastEffect: [FiberNode],
          lanes: 0,
          childLanes: 1,
          alternate: [Circular *2],
          actualDuration: 0,
          actualStartTime: -1,
          selfBaseDuration: 0,
          treeBaseDuration: 0,
          _debugID: 10782,
          _debugSource: [Object],
          _debugOwner: [FiberNode],
          _debugNeedsRemount: false,
          _debugHookTypes: null
        },
        actualDuration: 0,
        actualStartTime: -1,
        selfBaseDuration: 0,
        treeBaseDuration: 0,
        _debugID: 10782,
        _debugSource: {
          fileName: '/Users/lukasgermerott/Dev/flundr/clientnew/src/components/Register.tsx',
          lineNumber: 61,
          columnNumber: 12
        },
        _debugOwner: FiberNode {
          tag: 0,
          key: null,
          elementType: [Function: RegisterComponent],
          type: [Function: RegisterComponent],
          stateNode: null,
          return: [FiberNode],
          child: [Circular *2],
          sibling: null,
          index: 0,
          ref: null,
          pendingProps: {},
          memoizedProps: {},
          updateQueue: [Object],
          memoizedState: [Object],
          dependencies: [Object],
          mode: 0,
          flags: 0,
          nextEffect: null,
          firstEffect: null,
          lastEffect: null,
          lanes: 0,
          childLanes: 0,
          alternate: [FiberNode],
          actualDuration: 0,
          actualStartTime: -1,
          selfBaseDuration: 0,
          treeBaseDuration: 0,
          _debugID: 10780,
          _debugSource: [Object],
          _debugOwner: null,
          _debugNeedsRemount: false,
          _debugHookTypes: [Array]
        },
        _debugNeedsRemount: false,
        _debugHookTypes: null
      },
      '__reactProps$sikt1ggzmx': {
        onSubmit: [Function: submit],
        'data-testid': 'formular',
        children: {
          '$$typeof': Symbol(react.element),
          type: [Object],
          key: null,
          ref: null,
          props: [Object],
          _owner: [FiberNode],
          _store: {}
        }
      }
    }

但是当我在浏览器中记录相同的事件时,我得到了这个

<form>
   <div class=​"MuiGrid-root MuiGrid-container MuiGrid-spacing-xs-2 MuiGrid-direction-xs-column">
      <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
      <h5 class=​"MuiTypography-root MuiTypography-h5">​Registration​</h5>
   </div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <p class=​"MuiTypography-root MuiTypography-body1">​Persönliche Daten​</p>
   </div>​
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   <div class=​"MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">​…​</div>
   </div>​
</form>

这是对的,因为现在我可以通过事件访问这些值。我的 onsubmit 函数如下:

function submit(event: React.SyntheticEvent) {
        event.preventDefault();
        // Create target object to extract information from
        const target = event.target as typeof event.target & {
            email: { value: string };
            firstName: { value: string };
            lastName: { value: string };
            privacyPolicy: { checked: boolean };
          };
        console.log(target, "TARGET");
        const user : IUserRegistrationModel = {
            email: target.email.value,
            firstName: target.firstName.value,
            lastName: target.lastName.value,
            password: password,
            privacyPolicy: target.privacyPolicy.checked,
        };
        dispatch(authActions.register(user));
    }

测试中的问题是:当它提交事件时,它无法从事件中提取值而只是崩溃。对于浏览器事件,它工作正常。

你们有什么想法吗?

编辑:复制示例 https://codesandbox.io/s/brave-goldberg-8hfri?file=/src/App.tsx

这是这个的副本:

The problem you have it with trying to access the input directly from event.target. You should access it from event.target.elements instead: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements.

基于给定的沙箱,我能够通过更新以下代码使测试通过:

function onSubmit(event: React.SyntheticEvent<HTMLFormElement>) {
  event.preventDefault();
  // Create target object to extract information from
  const payload = event.currentTarget.elements as typeof event.currentTarget.elements & {
    email: { value: string };
  };
  console.log(payload.email.value);
  setShow(true);
}