Search code examples
reactjsreact-testing-library

@testing-library/react test form onSubmit


In a simple scenario like so

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>

How do I make sure that the form gets submitted when the submit button is clicked?

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

???

How do I test if onSubmit() has been called or maybe form has been submitted?


Solution

  • Basically, here is what I "solved" it:

    // 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)}/>
    
    }
    

    Now the test's file:

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