我有一个有状态组件,该组件调度一个动作并从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);
}
我想像下面这样测试该组件:
我开始如下编写测试:
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();
});
});
但是,即使以上方法也无法工作。请问这是测试此代码的正确要求,还是有更好的方法,请帮助我编写测试以涵盖这些要求。我似乎无法为此解决一切。
谢谢,谢谢。