React和Jest,如何测试状态变化并检查另一个组件?

41

React - 测试工具文档

我有一个Login组件,如果this.state.error为true,则会显示一个Notification组件。

现在我正在编写一个Jest测试来测试它。

import React from 'react'
import ReactTestUtils from 'react-dom/test-utils';
import { shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import Login from './Login'
import Notification from '../common/Notification'

describe('<Login /> component', () => {
    it('should render', () => {
        const loginComponent = shallow(<Login />);
        const tree = toJson(loginComponent);
        expect(tree).toMatchSnapshot();
    });

    it('should contains the words "Forgot Password"', () => {
        const loginComponent = shallow(<Login />);
        expect(loginComponent.contains('Forgot Password')).toBe(true);
    });

    // This test fails
    it('should render the Notification component if state.error is true', () => {
        const loginComponent = ReactTestUtils.renderIntoDocument(
            <Login />
        );

        const notificationComponent = ReactTestUtils.renderIntoDocument(
            <Notification />
        );

        loginComponent.setState({
            error: true
        }, expect(ReactTestUtils.isDOMComponent(notificationComponent)).toBe(true));
    });
});

然而目前测试失败了,我不确定原因

在此输入图片描述

在我的代码的最后部分,我也尝试过这个,但无济于事

loginComponent.setState({
        error: true
    }, expect(ReactTestUtils. isElement(notificationComponent)).toBe(true));

https://facebook.github.io/react/docs/test-utils.html

我的 Login 组件的 render() 方法

render() {
    const usernameError = this.state.username.error;
    const error = this.state.error;
    const errorMsg = this.state.errorMsg;

    return (
        <div className="app-bg">
            { error &&
                <Notification message={ errorMsg } closeMsg={ this.closeMessage }/>
            }
            <section id="auth-section">
                <header>
                    <img src="static/imgs/logo.png"/>
                    <h1>tagline</h1>
                </header>

在将state.error设置为true后,我尝试使用此方法测试Notification组件

it('should render the Notification component if state.error is true', () => {
    const loginComponent = ReactTestUtils.renderIntoDocument(
        <Login />
    );

    const notificationComponent = ReactTestUtils.renderIntoDocument(
        <Notification />
    );

    // loginComponent.setState({
    //  error: true
    // }, expect(ReactTestUtils.isDOMComponent(notificationComponent)).toBe(true));

    const checkForNotification = () => {
        const login = shallow(<Login />);
        expect(login.find(Notification).length).toBe(1);
    };

    loginComponent.setState({
        error: true
    }, checkForNotification());
});

但那个测试也失败了。

同时尝试 const login = mount(<Login />);


还有其他人在使用Jest和React测试工具时遇到问题吗?


你使用什么主题? - Cams Boyfriend
2个回答

79

搞定了!不需要使用React测试工具

it('should render the Notification component if state.error is true', () => {
    const loginComponent = shallow(<Login />);
    loginComponent.setState({ error: true });
    expect(loginComponent.find(Notification).length).toBe(1);
});

这将在Login组件中将错误状态设置为true,然后检查Login组件是否包含Notification组件。


你的组件使用Redux吗?当我调用setState时出现错误,我怀疑是Redux的问题。 - jcollum
1
@jcollum 在我的例子中我没有使用Redux,但是这个方法仍然适用于测试连接的组件。 - Leon Gaban
4
更新 useState 状态怎么样?我真的需要它。 - kafinsalim
这个怎么在RTL中实现?不是酶。 - Antimatterr

4

这段代码需要进行一些重构。应该将Notification组件放在一个更全局的组件中(比如页面包装器或其他容器),并且只有在全局reducer中存在错误时才渲染,否则应该渲染nullLogin组件可能不应该负责通知的责任和业务逻辑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接