我正在尝试测试Redux操作,并需要协助测试带有副作用的操作。
这是我的行动:
export function login(email, password) {
return dispatch => {
dispatch(setLoginSuccess(false));
loginApi(email, password, error => {
dispatch(setLoginPending(false));
if (!error) {
dispatch(setLoginSuccess(true));
} else {
dispatch(setLoginError(error));
}
});
}
}
以下是用于验证用户身份的loginApi函数:
export function loginApi(email, password, callback) {
if (email === 'test@test.com' && password == '123') {
return callback(null);
} else {
return callback(new Error('Please provide valid email and password'));
}
};
此外,我在使用Enzyme和Jest模拟我的组件中的表单提交时遇到了问题。
以下是相同的代码:
render() {
let {email, password, emailValid} = this.state;
let {isLoginPending, isLoginSuccess, loginError} = this.props;
return (
<div className="col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2 col-xs-10 col-xs-offset-1">
<h3 className="text-center">Login</h3>
<form className="login-form" onSubmit={this.handleSubmit.bind(this)}>
<div className={emailValid? "form-group has-success" : (emailValid == undefined)? "form-group": "form-group has-error"}>
<label>Email address</label>
<input type="email" name="email" className="form-control" ref="userEmail"
placeholder="Enter your email" onChange={this.handleChange.bind(this)}/>
</div>
{/* Checking if email valid or not */}
{this.props.emailValid? "" : (this.props.emailValid == undefined)? "" : <p className="text-danger">Please provide a valid email!</p>}
<div className="form-group">
<label>Password</label>
<input type="password" name="password" className="form-control" ref="userPassword"
placeholder="Enter your password" onChange={this.handleChange.bind(this)}/>
</div>
<button type ="submit" className="btn btn-primary btn-block" disabled={!this.props.emailValid}>Get Started</button>
{/* Displaying error messages */}
{ loginError && <div className="auth-error-msg"><p className="text-danger">{loginError.message}</p></div> }
</form>
</div>
);
};
以下是handleSubmit事件的代码:
handleSubmit(e){
e.preventDefault();
this.props.login(this.refs.userEmail.value, this.refs.userPassword.value);
this.setState({
email: '',
password: ''
});
}
我试图以这种方式模拟提交事件:
it('should render 1 error block on submitting invalid form', () => {
// Render a checkbox with label in the document
const spy = jest.fn();
const component = shallow(<Login login={spy}/>);
const form = component.find('form').simulate('submit');
});
但它目前抛出一个错误,因为它找不到preventDefault。我该如何测试这个事件?
答案 0 :(得分:1)
我建议你拆分测试。提交表单和测试操作是两回事。要使用jest测试操作,您需要将操作分派给模拟商店,并查看哪个是商店的最终状态。像这样:
describe('actions', () => {
let store
beforeEach(() => {
store = mockStore({})
})
it('should dispatch the correct actions', () => {
const expectedActions = [
{ type: 'action1', ...arguments },
{ type: 'action2', ...arguments }
]
store.dispatch(login('user', 'password'))
expect(store.getActions()).toEqual(expectedActions)
})
})
您可以执行多个测试用例,将预期的操作调整为您作为参数传递的内容。
为了创建模拟商店,有多个包可以完成这项工作。这是一个支持thunks的例子:
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)
export default mockStore
我个人不会花太多精力测试表单提交的内容。最后,这是一个标准的html,所以我会专注于你自己构建的组件。
另一个提示:如果您已经完成了使用redux
的所有麻烦,请不要回到正常状态。通过使用普通的reducer并将其转换到您的状态,您所拥有的setState
将更容易实现和测试。