Error: Not implemented: HTMLFormElement.prototype.submit

Published on September 24, 2021

If you ever tried to test a real form submission with Jest and JSDOM, you have probably seen this error:

title: Error: Not implemented: HTMLFormElement.prototype.submit

The pattern I use in this cases is wrapping the form in the tests with a FormMock component:

const onSubmit = jest.fn();
render(<MyComponentWithAForm />, {
wrapper: () => <FormMock onSubmit={onSubmit} />,
});

userEvent.click(scree.getByRole('button'));

expect(onSubmit).toHaveBeenCalledWith({
method: 'post',
action: '/foo-bar',
data: {
foo: 'bar',
},
target: '_blank',
});

And here's the implementation of the FormMock component:

import React, { FC, FormEventHandler } from 'react';

interface Data {
method: string;
action: string;
target: string;
data: Record<string, unknown>;
}

interface Props {
onSubmit?(data: Data): void;
}

export const FormMock: FC<Props> = ({ onSubmit, children }) => {
const handleFormSubmit: FormEventHandler = (e) => {
if (e.target instanceof HTMLFormElement) {
// Make sure prevented events don't fire the "onSubmit" method
if (!e.defaultPrevented) {
onSubmit?.({
method: e.target.method,
action: e.target.action,
target: e.target.target,
data: Object.fromEntries(new FormData(e.target)),
});
}

e.preventDefault();
}
};

return <div onSubmit={handleFormSubmit}>{children}</div>;
};