使用Jest和Enzyme测试ReactJs组件中的状态道具和事件

时间:2018-11-08 16:08:53

标签: reactjs jestjs enzyme

我有一个有状态组件,该组件调度一个动作并从redux获取状态,如下所示:

const mapStateToProps = state => {
    return {
        status: state.signUpReducer.status,
        message: state.signUpReducer.message
    }
}

const mapDispatchToProps = dispatch => {
    return {
        sign_up_start: credentials => dispatch( sign_up_start(credentials) ),
    }
}

组件的状态如下:

state = {
    formIsValid: false,
    formControls: {
        email: {
            value: "",
            valid: false,
            validationRules: {
                isEmail: true,
                isRequired: true
            },
            placeholderText: "Email Address",
            touched: false
        },
        password: {
            value: "",
            valid: false,
            touched: false,
            validationRules: {
                isRequired: true,
            },
            placeholderText: "Password"
        }
    }
};

我使用本地状态来处理表单onChange事件。

render () {
    return (
        <div>
            <Header />

            <div className={styles.signUpContainer}>
                <div className={styles.signUp}>SIGN UP</div>

                <div className={styles.signUpForm}>

                    <CustomInput type="email" name="email" 
                          placeholder={this.state.formControls.email.placeholderText}
                          value={this.state.formControls.email.value}
                          onChange={this.inputChangeHandler}
                          valid={this.state.formControls.email.valid.toString()}
                          touched={this.state.formControls.email.touched.toString()}
                    />


                    <CustomInput type="password" name="password" 
                          placeholder={this.state.formControls.password.placeholderText}
                          value={this.state.formControls.password.value}
                          onChange={this.inputChangeHandler}
                          valid={this.state.formControls.password.valid.toString()}
                          touched={this.state.formControls.password.touched.toString()}
                    />

                    <Button onClick={this.formSubmitHandler} disabled={!this.state.formIsValid}>CREATE MY ACCOUNT</Button>


                </div>
            </div>

        </div>
    );
}

有一个用于处理onClick事件的自定义按钮组件,该组件如下所示:

const Button = props => {
    return (
        <button className={styles.button} {...props}>{props.children}</button>
    );
}

单击<Button />组件时,将调用下面的formSubmitHandler方法,请注意,该方法位于父方法上,而不是Button组件上。

formSubmitHandler = event => {
    event.preventDefault();

    const formData = {};
    for (let formElementId in this.state.formControls) {
        formData[formElementId] = this.state.formControls[formElementId].value
    }

    this.props.sign_up_start(formData);
}

表单处理程序会调度sign_up_start,它是带有redux的句柄,如果成功,它将返回prop状态200或422,否则,我将像下面这样挂接到componentWillReceiveProps(nextProps) {}上:

redirectOrNotifyOnStatusChange(nextProps) {
    if (nextProps.status === 200) {
        //show success notification
        return this.navigateTo('/auth');
    }
    if ((nextProps.status === 422) || !(nextProps.message === this.props.message)) {
        //show notification
        return window.alert('Opps', nextProps.message);
    }
} 


componentWillReceiveProps(nextProps) {
    this.redirectOrNotifyOnStatusChange(nextProps);
}

我想像下面这样测试该组件:

  1. 传递来自redux的初始道具状态和消息,我知道在componentDidMount上它将为空
  2. 测试单击Button时,是否调用formSubmitHandler方法,并且该方法调用`this.props.sign_up_start
  3. 观察componentWillReceiveProps的时间,并测试nextProps.status为200时,它将重定向到auth的页面
  4. 还测试状态为422时是否显示弹出窗口。

我开始如下编写测试:

import React from 'react';
import {mount} from 'enzyme';
import { SignUp } from './SignUp.page';
import Button from '../../components/Button';


describe('<SignUp />', () => {

    it('test formSubmitHandler called props.sign_up_start', () => {

        const props = {
            sign_up_start: jest.fn(),
        }

        const wrapper = mount(<SignUp {...props} />);
        const instance = wrapper.instance();

        jest.spyOn(instance, 'formSubmitHandler');
        wrapper.find(Button).simulate('click');
        expect(instance.formSubmitHandler).toHaveBeenCalled();

        // expect(props.sign_up_start).toHaveBeenCalled();

    });

});

但是,即使以上方法也无法工作。请问这是测试此代码的正确要求,还是有更好的方法,请帮助我编写测试以涵盖这些要求。我似乎无法为此解决一切。

谢谢,谢谢。

0 个答案:

没有答案