【问题标题】:@testing-library/react test form onSubmit@testing-library/react 测试表单 onSubmit
【发布时间】:2020-05-07 21:39:02
【问题描述】:

在这样的简单场景中

function onSubmit() { e.preventDefault(); /* Some Submit Logic */ }

<form data-testid="form" onSubmit={(e) => onSubmit(e)}>
   <button type="submit" data-testid="submit-button">Submit</button>
</form>

如何确保在单击提交按钮时提交表单?

const { queryByTestId } = render(<LoginForm/>);
const LoginForm = queryByTestId("form")
const SubmitButton = queryByTestId("submit-button")
fireEvent.click(SubmitButton)

???

如何测试是否已调用 onSubmit() 或是否已提交表单?

【问题讨论】:

    标签: reactjs react-testing-library


    【解决方案1】:

    基本上,这是我“解决”的问题:

    // LoginForm.js
    
    export function LoginForm({ handleSubmit }) {
    
         const [name, setName] = useState('');
    
         function handleChange(e) {
             setName(e.target.value)
         }
    
         return (
             <form data-testid="form" onSubmit={() => handleSubmit({ name })}>
                  <input required data-testid="input" type="text" value={name} onChange={(e) => handleChange(e)}/>
                  <button type="submit" data-testid="submit-button">Submit</button>
             </form>
         )
    }
    
    export default function LoginPage() {
    
        function handleSubmit(e) {
            // submit stuff
        }
    
        return <LoginForm handleSubmit={(e) => handleSubmit(e)}/>
    
    }
    

    现在测试的文件:

    // LoginForm.test.js
    
    import React from 'react';
    import { render, fireEvent } from "@testing-library/react";
    import LoginPage, { LoginForm } from "./LoginPage";
    
    it("Form can be submited & input field is modifiable", () => {
    
        const mockSubmit = jest.fn();
        const { debug, queryByTestId } = render(<LoginForm handleSubmit={mockSubmit}/>);
    
        fireEvent.change(queryByTestId("input"), { target: { value: 'Joe Doe' } }); // invoke handleChange
        fireEvent.submit(queryByTestId("form"));
    
        expect(mockSubmit).toHaveBeenCalled(); // Test if handleSubmit has been called 
        expect(mockSubmit.mock.calls).toEqual([[{name: 'Joe Doe'}]]); // Test if handleChange works
    
    });
    

    【讨论】:

    • 如果您没有 handleSubmit 道具,这将如何工作?在很多原因中,组件不希望传入一个 handleSubmit 道具——为什么会这样?必须为仅用于测试的组件传递一个 prop 似乎非常违反直觉?
    • 同意@alexr89 ...要求组件方法都通过props传递基本上是代码气味以满足测试。
    【解决方案2】:

    我建议使用nock 拦截从表单发送的请求,然后返回模拟响应。 例如:

    nock('https://foo.bar').post('/sign-up', formValues).reply(201);
    

    但我想知道更好的解决方案。

    【讨论】:

      猜你喜欢
      • 2019-05-21
      • 2019-11-11
      • 1970-01-01
      • 2021-04-26
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      相关资源
      最近更新 更多