Redux 表单 onSubmit 在测试中值空对象
Redux form onSubmit values empty object in testing
onSubmit 处理程序中的值始终为空对象。如何将一些值传递给它以便我可以测试追加?
测试:
const store = createStore(combineReducers({ form: formReducer }));
const setup = (newProps) => {
const props = {
...newProps,
};
expect.spyOn(store, 'dispatch');
const wrapper = mount(
<Provider store={store}>
<RegisterFormContainer {...props} />
</Provider>,
);
return {
wrapper,
props,
};
};
describe('RegisterFormContainer.integration', () => {
let wrapper;
it('should append form data', () => {
({ wrapper } = setup());
const values = {
userName: 'TestUser',
password: 'TestPassword',
};
expect.spyOn(FormData.prototype, 'append');
// Passing values as second argument DOESN'T work, it's just an empty object
wrapper.find('form').simulate('submit', values);
Object.keys(values).forEach((key) => {
expect(FormData.prototype.append).toHaveBeenCalledWith(key, values[key]));
});
expect(store.dispatch).toHaveBeenCalledWith(submit());
});
});
容器:
const mapDispatchToProps = dispatch => ({
// values empty object
onSubmit: (values) => {
const formData = new FormData();
Object.keys(values).forEach((key) => {
formData.append(key, values[key]);
});
return dispatch(submit(formData));
},
});
export default compose(
connect(null, mapDispatchToProps),
reduxForm({
form: 'register',
fields: ['__RequestVerificationToken'],
validate: userValidation,
}),
)(RegisterForm);
组件:
const Form = ({ error, handleSubmit }) => (
<form onSubmit={handleSubmit} action="">
<Field className={styles.input} name="username" component={FormInput} placeholder="Username" />
<button type="submit">
Register
</button>
</form>
);
simulate 接受第二个参数,即事件对象。
wrapper.find('form').simulate('submit', { target });
这里的问题是您忽略了实际表单的工作方式。如果您尝试在表单上模拟 submit
事件,则需要在 redux 存储中存储实际的表单值,以便 redux-form 提取这些值并将它们传递给 onSubmit
处理程序.
根本问题是您不应该在单元测试中端到端地测试 redux-form
的功能。测试您的应用程序是否端到端工作应该在集成测试级别上进行。
针对这种情况我的建议是
- 假设只要您正确使用
redux-form
,表单到商店的集成就可以正常工作。
- 编写测试以确保您传递给
redux-form
相关组件的函数和值是正确的并且可以正常工作。
- 保持测试组件和容器的分离,这篇文章应该给你a nice overview on how to test connected components
因此,请彻底测试 mapDispatchToProps
以确保它生成的函数的行为符合您的预期。然后确保将正确的函数和属性传递到组件和容器中的正确位置。之后,只要您正确使用 redux 和 redux-form,您就可以安全地假设一切正常。
希望对您有所帮助!
onSubmit 处理程序中的值始终为空对象。如何将一些值传递给它以便我可以测试追加?
测试:
const store = createStore(combineReducers({ form: formReducer }));
const setup = (newProps) => {
const props = {
...newProps,
};
expect.spyOn(store, 'dispatch');
const wrapper = mount(
<Provider store={store}>
<RegisterFormContainer {...props} />
</Provider>,
);
return {
wrapper,
props,
};
};
describe('RegisterFormContainer.integration', () => {
let wrapper;
it('should append form data', () => {
({ wrapper } = setup());
const values = {
userName: 'TestUser',
password: 'TestPassword',
};
expect.spyOn(FormData.prototype, 'append');
// Passing values as second argument DOESN'T work, it's just an empty object
wrapper.find('form').simulate('submit', values);
Object.keys(values).forEach((key) => {
expect(FormData.prototype.append).toHaveBeenCalledWith(key, values[key]));
});
expect(store.dispatch).toHaveBeenCalledWith(submit());
});
});
容器:
const mapDispatchToProps = dispatch => ({
// values empty object
onSubmit: (values) => {
const formData = new FormData();
Object.keys(values).forEach((key) => {
formData.append(key, values[key]);
});
return dispatch(submit(formData));
},
});
export default compose(
connect(null, mapDispatchToProps),
reduxForm({
form: 'register',
fields: ['__RequestVerificationToken'],
validate: userValidation,
}),
)(RegisterForm);
组件:
const Form = ({ error, handleSubmit }) => (
<form onSubmit={handleSubmit} action="">
<Field className={styles.input} name="username" component={FormInput} placeholder="Username" />
<button type="submit">
Register
</button>
</form>
);
simulate 接受第二个参数,即事件对象。
wrapper.find('form').simulate('submit', { target });
这里的问题是您忽略了实际表单的工作方式。如果您尝试在表单上模拟 submit
事件,则需要在 redux 存储中存储实际的表单值,以便 redux-form 提取这些值并将它们传递给 onSubmit
处理程序.
根本问题是您不应该在单元测试中端到端地测试 redux-form
的功能。测试您的应用程序是否端到端工作应该在集成测试级别上进行。
针对这种情况我的建议是
- 假设只要您正确使用
redux-form
,表单到商店的集成就可以正常工作。 - 编写测试以确保您传递给
redux-form
相关组件的函数和值是正确的并且可以正常工作。 - 保持测试组件和容器的分离,这篇文章应该给你a nice overview on how to test connected components
因此,请彻底测试 mapDispatchToProps
以确保它生成的函数的行为符合您的预期。然后确保将正确的函数和属性传递到组件和容器中的正确位置。之后,只要您正确使用 redux 和 redux-form,您就可以安全地假设一切正常。
希望对您有所帮助!