最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React hook form failed to submit within react testing library test - Stack Overflow

programmeradmin6浏览0评论

I am writing a test to ensure my form is submitting using react testing library and I am also using react hook form. My submit method is failing to be called within my test. I am greeting with the following error when this test runs:

● reset password should send

    expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

Can someone explain what I am doing incorrectly?

My ponent

const ResetPassword = () => {
    const { handleSubmit } = useForm();

    const onSubmit = (resetFormData: { email: string }) => {
        const { email } = resetFormData;
        // sends email using external API
    };

    return (
            <form onSubmit={handleSubmit(onSubmit)}>
                <input
                    name="email"
                    type="text"
                    placeholder="Email Address"
                />
                <button type="submit">
                    Send Email
                </button>
            </form>
    );
};

export default ResetPassword;

My Test File

import userEvent from '@testing-library/user-event';
import { render, cleanup, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

afterEach(cleanup);

it('reset password should send', async () => {
    render(<ResetPassword />);

    const handleSubmit = jest.fn();
    const onSubmit = jest.fn();
    const value = '[email protected]';
    const input = screen.getByPlaceholderText(/Email Address/i);
    await userEvent.type(input, value);

    await act(async () => {
        userEvent.click(screen.getByRole('button', { name: /Send Email/i }));
    });

    expect(onSubmit).toHaveBeenCalled();
});

I am writing a test to ensure my form is submitting using react testing library and I am also using react hook form. My submit method is failing to be called within my test. I am greeting with the following error when this test runs:

● reset password should send

    expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

Can someone explain what I am doing incorrectly?

My ponent

const ResetPassword = () => {
    const { handleSubmit } = useForm();

    const onSubmit = (resetFormData: { email: string }) => {
        const { email } = resetFormData;
        // sends email using external API
    };

    return (
            <form onSubmit={handleSubmit(onSubmit)}>
                <input
                    name="email"
                    type="text"
                    placeholder="Email Address"
                />
                <button type="submit">
                    Send Email
                </button>
            </form>
    );
};

export default ResetPassword;

My Test File

import userEvent from '@testing-library/user-event';
import { render, cleanup, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

afterEach(cleanup);

it('reset password should send', async () => {
    render(<ResetPassword />);

    const handleSubmit = jest.fn();
    const onSubmit = jest.fn();
    const value = '[email protected]';
    const input = screen.getByPlaceholderText(/Email Address/i);
    await userEvent.type(input, value);

    await act(async () => {
        userEvent.click(screen.getByRole('button', { name: /Send Email/i }));
    });

    expect(onSubmit).toHaveBeenCalled();
});
Share Improve this question asked Jan 31, 2021 at 14:51 RafaelRafael 5,2493 gold badges20 silver badges29 bronze badges 1
  • 1 Defining a locally scoped function onSubmit with just the same name in your test will not do anything. For the interpreter this is a pletely different function. You need to mock the actual function that gets called in you ponent. Also this is testing implementation details and is generally not remended. A better way to test it would be to mock the actual fetch that happens on submit. – trixn Commented Jan 31, 2021 at 14:58
Add a ment  | 

1 Answer 1

Reset to default 5

For anyone who stumbles upon this in the future, I read the article mented by Trixin and rewrote my unit test. Here's a slim version of it now. Basically, I'm testing for what the user would experience rather than the developer to avoid false positives/negatives

Component

const ResetPassword = () => {
    const { handleSubmit } = useForm();
    const [message, setMessage] = useState(''); // I alert the 
    // user of a successful sent message
    const onSubmit = (resetFormData: { email: string }) => {
        const { email } = resetFormData;
        // sends email using external API
    };

    return (
            <form onSubmit={handleSubmit(onSubmit)}>
                <input
                    name="email"
                    type="text"
                    placeholder="Email Address"
                />
                <button type="submit">
                    Send Email
                </button>
                {message}
            </form>
    );
};

export default ResetPassword;

Test File

it('reset password should send', async () => {
    render(<ResetPassword />);

    const value = '[email protected]';
    const input = screen.getByPlaceholderText(/Email Address/i);
    await userEvent.type(input, value);

    await act(async () => {
        fireEvent.click(screen.getByText(/Send Email/i));
    });
    expect(screen.getByText('Message Sent!')).toBeInTheDocument();
});

it('reset password should not send', async () => {
    render(<ResetPassword />);

    const input = screen.getByPlaceholderText(/Email Address/i);
    const inValidEmail = 'user.';
    
    await userEvent.type(input, inValidEmail);
    await act(async () => {
        fireEvent.click(screen.getByText(/Send Email/i));
    });
    expect(screen.getByText('Invalid email address')).toBeInTheDocument();

    // reset input value
    fireEvent.change(input, { target: { value: '' } });
    await userEvent.type(input, '');
    // user hits spacebar and tries to submit
    await act(async () => {
        fireEvent.keyDown(input, {
            charCode: 62,
            code: 62,
            key: 'Space Bar',
            keyCode: 62,
        });
    });

    await act(async () => {
        fireEvent.click(screen.getByText(/Send Email/i));
    });
    expect(screen.getByText('Email is required')).toBeInTheDocument();
});
发布评论

评论列表(0)

  1. 暂无评论