【问题标题】:how to test button that call submit form using jest and react testing library如何使用 jest 和反应测试库测试调用提交表单的按钮
【发布时间】:2021-05-12 13:19:11
【问题描述】:

所以我正在尝试测试 onSubmit 函数是否在单击按钮时被触发 - 我这样做的方法是通过测试 onSubmit 函数的内部获取调用(axios post 方法)

测试

describe('RecipeSearch', () => {
    test('submit button should return post function to recipes/search/', () => {
        let mock = new MockAdapter(axios);
        userEvent.selectOptions(screen.getByRole('combobox'), 'Sweet');
        userEvent.click(screen.getByText('Search'));

        const config = {
            headers: {
                'Content-Type': 'application/json',
            },
        };
        const searchRecipes = mock.onPost(
            `${process.env.REACT_APP_API_URL}/recipes/search/`,
            { flavor_type: 'Sweet' },
            { config }
        );
        expect(searchRecipes).toHaveBeenCalled();
    });
});

错误

    expect(received).toHaveBeenCalled()

    Matcher error: received value must be a mock or spy function

    Received has type:  object
    Received has value: {"abortRequest": [Function abortRequest], "abortRequestOnce": [Function abortRequestOnce], "networkError": [Function networkError], "networkErrorOnce": [Function networkErrorOnce], "passThrough": [Function passThrough], "reply": [Function reply], "replyOnce": [Function replyOnce], "timeout": [Function timeout], "timeoutOnce": [Function timeoutOnce]}

函数

const recipeSearch = (props) => {
    const [formData, setFormData] = useState({
        flavor_type: 'Sour',
    });

    const { flavor_type } = formData;

    const [loading, setLoading] = useState(false);

    const onChange = (e) => setFormData({ ...formData, [e.target.name]: e.target.value });

    const onSubmit = (e) => {
        e.preventDefault();

        const config = {
            headers: {
                'Content-Type': 'application/json',
            },
        };

        setLoading(true);
        axios
            .post(
                `${process.env.REACT_APP_API_URL}/recipes/search/`,
                {
                    flavor_type,
                },
                config
            )
            .then((res) => {
                setLoading(false);
                props.setRecipes(res.data);
                window.scrollTo(0, 0);
            })
            .catch((err) => {
                setLoading(false);
                window.scrollTo(0, 0);
            });
    };

    return (
        <form  onSubmit={(e) => onSubmit(e)}>
            <div>
                <div>
                    <div>
                        <label htmlFor='flavor_type'>Choose Flavor</label>
                        <select
                            name='flavor_type'
                            onChange={(e) => onChange(e)}
                            value={flavor_type}
                        >
                            <option value='Sour'>Sour</option>
                            <option>Sweet</option>
                            <option>Salty</option>
                        </select>
                    </div>

                    <div>
                            <button type='submit'>Search</button> 
                    </div>
                </div>
            </div>
        </form>
    );
};

我已经添加了整个测试和组件代码,所以帮助会更容易。 提前致谢

(添加 onChange + onSubmit 函数)

【问题讨论】:

  • 有时 Formik 需要一些滴答声才能通过验证和一切——您是否尝试过将这种期望包装在 await waitFor() 中?
  • 试过了,还是不行。
  • 在你的组件代码中,onSubmit 函数来自哪里?

标签: reactjs testing jestjs react-testing-library


【解决方案1】:

您是否尝试通过文本选择按钮:

 describe('RecipeSearch', () => {
    test('test clicking the button triggers the onSubmit function', () => {
        const onSubmit = jest.fn();
        render(<RecipeSearch onSubmit={onSubmit} />);
        userEvent.selectOptions(screen.getByRole('combobox'), 'Sour');
        userEvent.click(screen.getByText('Search'));
        expect(onSubmit).toHaveBeenCalled();
    });
});

我不确定 getByRole 在您的第一次尝试中如何处理第二个参数,但 getByText 应该可以工作。

【讨论】:

  • 感谢您的评论,但不幸的是测试仍然无法正常工作。
【解决方案2】:

创建onSubmit 模拟并将其作为道具传递将不起作用,因为onSubmit 回调是组件内部而不是道具 - 您无法从测试中访问它。

与其测试onSubmit是否被调用,不如测试触发提交事件的结果。在这种情况下,这可能意味着验证是否发出了 axios 请求。

【讨论】:

  • 谢谢你帮了我很多,现在我明白为什么测试一直失败了!但是有没有一种方法可以模拟内部函数以在测试中使用?还是我应该手动将函数导入测试?
  • 没有办法模拟内部函数。如果您真的需要,您可以从外部文件导入它并在测试期间模拟导入的函数。
  • 话虽如此,我不建议仅仅为了测试目的而更改您的代码。正如我所说,您应该测试触发onSubmit 操作的结果。
  • 谢谢你帮了很多忙。我会试一试
  • 所以我尝试测试 onSubmit 函数的结果,但仍然测试失败。
猜你喜欢
  • 2015-01-22
  • 1970-01-01
  • 2020-08-15
  • 2020-03-29
  • 2019-11-20
  • 1970-01-01
  • 2020-08-27
  • 2019-04-22
  • 1970-01-01
相关资源
最近更新 更多