React组件测试疑问:Wrapper.find未找到类及测试范围咨询
React组件测试疑问:Wrapper.find定位失败与测试范围困惑
我最近在测试一个React组件时遇到了两个问题,先贴一下我的组件代码:
const User = ({ users }) => ( <div className="displayContainer"> {users && users.length > 0 && users[0].username ? <div className="userOnShow"> <img className="userImage" alt="no image yet"/> <div>{users[0].username}, {users[0].age}</div> </div> : <div className="noOneLeft"> {'Sorry, no new people in your area'} </div> } </div> )
我的两个疑问:
- 这个组件应该测试哪些内容?比如是不是只需要测试是否渲染对应类名的元素就行?我感觉三元表达式的分支测试属于集成测试范畴?
- 核心问题是写测试用例时,
Wrapper.find找不到指定类名的元素,我的测试代码片段如下:
describe.only('DisplayingUser', () => { let wrapper; const usersStub = {remainingUsers: []} it('expects the props to be correct', () => { wrapper = shallow( <User users={usersStub.remainingUsers} /> ) // 这里尝试查找.noOneLeft或者.userOnShow都找不到 }) })
问题解答
关于测试范围的疑问
首先明确:这个组件的三元分支逻辑属于单元测试的范畴,因为所有逻辑都在单个组件内部,不需要依赖其他外部组件或服务。你需要覆盖的测试点包括:
- 当
users为空数组、不存在,或是第一个元素没有username时,是否渲染.noOneLeft元素,且提示文本正确 - 当
users是包含有效用户(带username)的数组时,是否渲染.userOnShow元素,同时验证用户名、年龄的文本内容是否正确,以及.userImage是否存在 - 无论哪种分支,外层的
.displayContainer都应该稳定渲染
别局限于只测试类名,组件的核心价值就是根据不同props展示对应内容,所以要把所有分支的渲染结果和内容准确性都覆盖到。
关于Wrapper.find找不到类的问题
看你的测试代码,usersStub.remainingUsers是空数组,理论上应该渲染.noOneLeft,找不到元素大概率是这几个原因:
- 组件导入/使用错误:检查测试里的
<User />是不是写错了组件名(你代码里写的<U...是截断了吧?要确保组件名和导入的一致) - 类名拼写失误:仔细核对测试里查找的类名和组件中的是否完全一致,比如有没有把
noOneLeft写成nooneLeft这类大小写或拼写错误 - 条件判断的细节:组件的触发条件是
users && users.length > 0 && users[0].username,空数组会走else分支,但如果你的users传递的是undefined/null,同样会走else分支。你可以在测试里加一行console.log(wrapper.debug()),打印出当前渲染的DOM结构,就能直观看到到底渲染了什么,快速定位问题 - shallow渲染的小坑:虽然这里都是原生HTML元素,shallow渲染不会有问题,但如果后续组件嵌套了子组件,shallow不会渲染子组件,但当前场景不影响
给你一个可以直接参考的正确测试示例:
describe('User Component', () => { it('renders noOneLeft block when users is empty', () => { const wrapper = shallow(<User users={[]} />); expect(wrapper.find('.noOneLeft').exists()).toBe(true); expect(wrapper.find('.noOneLeft').text()).toBe('Sorry, no new people in your area'); }); it('renders userOnShow with correct info when users have valid data', () => { const mockUsers = [{ username: 'Alice', age: 25 }]; const wrapper = shallow(<User users={mockUsers} />); expect(wrapper.find('.userOnShow').exists()).toBe(true); expect(wrapper.find('.userOnShow div').text()).toBe('Alice, 25'); expect(wrapper.find('.userImage').exists()).toBe(true); }); });
先通过wrapper.debug()看实际渲染内容,再针对性排查,问题很快就能解决。
内容的提问来源于stack exchange,提问作者The Walrus
相关产品推荐
相关产品推荐

