如何使用React Testing Library测试React Redux的Field组件及属性
问题解释与正确测试方案
1 测试现象的原因说明
你感知到的逻辑冲突其实是对getByRole参数的误解:getByRole('textbox', { name: xxx })里的name匹配的是输入框的可访问名称,对应你给Field组件传的label="Postcode"属性值,和Field组件自身用于表单提交的name属性(值为小写postcode)是完全独立的两个配置,所以当前这部分断言本身没有问题。
2 各属性的测试方案
2.1 测试label属性
你现有的断言已经间接验证了label配置,如果label值错误,getByRole会直接找不到对应输入框。也可以单独显式断言:
expect(screen.getByLabelText('Postcode')).toBeInTheDocument();
2.2 测试Field的小写name属性
Field的name属性最终会挂载到渲染出来的input元素的原生name属性上,直接断言属性值即可:
const postcodeInput = screen.getByRole('textbox', { name: 'Postcode' }); expect(postcodeInput).toHaveAttribute('name', 'postcode');
2.3 测试nonReduxFormInputProps配置
你传入的id: 'postcode'会落到input元素的原生id属性上,直接验证id即可,同时也可以校验label和input的关联是否正常:
expect(postcodeInput).toHaveAttribute('id', 'postcode'); // 额外校验label与输入框关联正确 expect(screen.getByLabelText('Postcode').id).toBe('postcode');
2.4 测试component属性是否为TextInput
分两种场景测试:
- 集成测试场景:给你的TextInput组件根元素加测试标识
data-testid="text-input-component",然后断言:expect(postcodeInput.closest('[data-testid="text-input-component"]')).toBeInTheDocument(); - 单元测试场景:直接mock Field组件,校验传入的props是否正确:
jest.mock('redux-form', () => ({ ...jest.requireActual('redux-form'), Field: jest.fn(() => null), })); it('should pass correct props to Field', () => { render(<TestForm />); expect(Field).toHaveBeenCalledWith(expect.objectContaining({ name: 'postcode', label: 'Postcode', nonReduxFormInputProps: { id: 'postcode' }, component: TextInput, }), expect.anything()); });
3 完整测试代码示例
import { render, screen } from '@testing-library/react'; import TestForm from './TestForm'; import { Field } from 'redux-form'; import TextInput from './TextInput'; // 集成测试:验证最终渲染结果符合预期 describe('postcode field render check', () => { it('should render with all correct configurations', () => { render(<TestForm />); const postcodeInput = screen.getByRole('textbox', { name: 'Postcode' }); expect(postcodeInput).toBeInTheDocument(); expect(postcodeInput).toHaveAttribute('name', 'postcode'); expect(postcodeInput).toHaveAttribute('id', 'postcode'); }); }); // 单元测试:验证props传递符合预期 jest.mock('redux-form', () => ({ ...jest.requireActual('redux-form'), Field: jest.fn(() => null), })); describe('postcode field prop check', () => { it('should pass all correct props to Field component', () => { render(<TestForm />); expect(Field).toHaveBeenCalledWith( expect.objectContaining({ name: 'postcode', label: 'Postcode', nonReduxFormInputProps: { id: 'postcode' }, component: TextInput }), expect.anything() ); }); });
内容的提问来源于stack exchange,提问作者HelloL
相关产品推荐
相关产品推荐

