如何使用笑话和反应测试库测试调用提交表单的按钮

Eli*_*med 7 testing reactjs jestjs react-testing-library

所以我试图测试 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();
    });
});

Run Code Online (Sandbox Code Playgroud)

错误

    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]}
Run Code Online (Sandbox Code Playgroud)

功能

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>
    );
};
Run Code Online (Sandbox Code Playgroud)

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

(添加了onChange + onSubmit函数)

Flo*_*Flo 0

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

 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();
    });
});
Run Code Online (Sandbox Code Playgroud)

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