react-bootstrap受控Form Control使用React Testing Library测试label关联报错解决方案
问题解决方案
错误根因
你遇到的报错由两个独立问题共同导致:
- 组件本身没有建立label和输入框的正确关联:HTML中
<label>标签需要通过for属性(React中对应props为htmlFor)关联对应表单控件的id属性,Testing Library需要这个关联才能正确执行getByLabelText查询 - 测试用例查询逻辑错误:
getByLabelText是匹配<label>标签的文本内容,你传入的/this is a test/i是输入框的value值,并非label的文本,当然匹配不到对应控件
修复步骤
1. 修复TextInput组件的关联逻辑
给Form.Label添加htmlFor属性,值和下方Form.Control的id保持一致:
class TextInput extends Component { render() { const { name, label, value, required, handleChange, t, } = this.props; return ( <React.Fragment> {/* 新增htmlFor属性,值为name和输入框id对应 */} <Form.Label htmlFor={name}>{label}</Form.Label> <Form.Control data-testid="text-input" id={name} value={value} name={name} onChange={handleChange} /> </React.Fragment> ); } } TextInput.propTypes = { handleChange: PropTypes.func, name: PropTypes.string, label: PropTypes.string, value: PropTypes.string }; export default withTranslation()(TextInput);
2. 修复测试用例的查询逻辑
如果要校验label和输入框的关联是否生效,用label的文本"Body"查询;如果要校验输入框的填充值是否正确,用getByDisplayValue或者直接校验元素value属性即可:
describe('TextInput', () => { const defaultProps = { name: "Title", label: "Body", type: "text", value: "this is a test", required: false, handleChange:jest.fn(), }; it("Renders TextInput Component with correct values", ()=>{ render( <I18nextProvider i18n={i18n}> <TextInput {...defaultProps}/> </I18nextProvider> ) expect(screen.queryByTestId("text-input")).toBeTruthy(); // 校验label和输入框关联正常,用label文本查询 const inputByLabel = screen.getByLabelText(/Body/i); expect(inputByLabel).toBeInTheDocument(); // 校验输入框的值正确 expect(inputByLabel).toHaveValue('this is a test'); // 也可以直接用displayValue查询值对应的输入框 expect(screen.getByDisplayValue(/this is a test/i)).toBeInTheDocument(); }) }
修复后即可正常通过测试。
内容的提问来源于stack exchange,提问作者lost9123193
相关产品推荐
相关产品推荐

