我正在开玩笑地做一个完整的覆盖范围测试。目前,我已经对几乎所有组件进行了测试,但是有一个handleSubmit函数,在该函数中,我进行了调度以接收表单事件数据,当我运行测试时,我告诉了我
TypeError: Cannot read property 'value' of undefined
10 | payload: {
11 | name: name.value,
> 12 | item: item.value,
| ^
13 | status: status.value }
14 | })
15 | }
我正在加载一个模拟存储,安装了所有组件,所有组件都经过测试,但是提交仍然失败。我的测试功能很简单:
it('testing submit', () => {
const form = component.find(`[data-test="submit"]`).first()
form.simulate('submit')
... and continues expecting some existences, but there aren't problems there
我已经尝试过:enzyme simulate submit form, Cannot read property 'value' of undefined
并尝试在模拟动作中解析事件值...
完整的模块代码是...
class Filters extends Component {
handleSubmit = event => {
event.preventDefault()
const {name, items, status} = event.target;
this.props.dispatch({
type: 'SEARCH_PLAYER',
payload: {
name: name.value,
item: item.value,
status: status.value }
})
}
render() {
return(
<div>
<form onSubmit={this.handleSubmit} data-test="submit">
<div className="form-group col-md-12 text-center"> ...
另一个非常疯狂的事情是我的测试识别出“ event.target.name.value”,而不是项目和状态。实际上,如果我从调度中删除项目和状态,则测试运行成功
答案 0 :(得分:2)
好像您在第12行使用item
,但是从items
中提取event.target
。
答案 1 :(得分:2)
您选择的处理值的方式有些奇怪。相反,应像这样通过state
处理值:Controlled Components
然后,您可以测试是否使用正确的值调用了this.props.dispatch()
。
旁注:避免在不必要时使用data
属性,因为它们会开始使您的DOM
变得多余。您可以通过find
,element
,element.className
,... and so on来选择className
。
工作示例:https://codesandbox.io/s/5j4474rkk(您可以通过点击屏幕左下方的Tests
标签来运行下面定义的测试。
components / Form / Form.js
import React, { Component } from "react";
import PropTypes from "prop-types";
export default class Form extends Component {
state = {
test: ""
};
static propTypes = {
dispatch: PropTypes.func.isRequired
};
handleChange = ({ target: { name, value } }) => {
this.setState({ [name]: value });
};
handleSubmit = e => {
e.preventDefault();
this.props.dispatch({
type: "SEARCH_PLAYER",
payload: {
test: this.state.test
}
});
};
render = () => (
<form onSubmit={this.handleSubmit} className="form-container">
<h1>Form Testing</h1>
<input
className="uk-input input"
type="text"
name="test"
placeholder="Type something..."
onChange={this.handleChange}
value={this.state.test}
/>
<button type="submit" className="uk-button uk-button-primary submit">
Submit
</button>
</form>
);
}
components / Form / __ tests __ / Form.js (shallowWrap
和checkProps
是可以在test/utils/index.js
中找到的自定义函数)
import React from "react";
import { shallowWrap, checkProps } from "../../../test/utils";
import Form from "../Form";
const dispatch = jest.fn();
const initialProps = {
dispatch
};
const initialState = {
test: ""
};
const wrapper = shallowWrap(<Form {...initialProps} />, initialState);
describe("Form", () => {
it("renders without errors", () => {
const formComponent = wrapper.find(".form-container");
expect(formComponent).toHaveLength(1);
});
it("does not throw PropType warnings", () => {
checkProps(Form, initialProps);
});
it("submits correct values to dispatch", () => {
const name = "test";
const value = "Hello World!";
const finalValues = {
type: "SEARCH_PLAYER",
payload: {
[name]: value
}
};
wrapper.find("input").simulate("change", { target: { name, value } }); // simulates an input onChange event with supplied: name (event.target.name) and value (event.target.value)
wrapper
.find(".form-container")
.simulate("submit", { preventDefault: () => null }); // simulates a form submission that has a mocked preventDefault (event.preventDefault()) to avoid errors about it being undefined upon form submission
expect(dispatch).toBeCalledWith(finalValues); // expect dispatch to be called with the values defined above
});
});