React中如何使用Jest mock单元函数覆盖if测试分支
问题场景
你在组件render方法中编写了如下分支逻辑,需要通过Jest mock工具方法覆盖两个分支的测试:
render() { let isNew = Boolean(domService.getQueryParamByName("isNew")); if(isNew) { return( // something ) } else { return(// return anything) } }
实现方案
核心思路是在不同测试用例中,控制domService.getQueryParamByName的返回值,分别让Boolean(返回值)为true和false,触发对应分支渲染后做断言即可,常用两种写法:
方案1:mock整个domService模块
在测试文件顶部直接mock domService模块,将getQueryParamByName替换为jest mock函数,每个用例单独配置返回值:
// 注意jest.mock要写在import语句之前 jest.mock('@/utils/domService', () => ({ getQueryParamByName: jest.fn() })) import domService from '@/utils/domService' import { mount } from '@testing-library/react' import TargetComponent from './TargetComponent' describe('组件render分支测试', () => { // 每个用例执行前清空mock记录,避免互相影响 beforeEach(() => { jest.clearAllMocks() }) it('URL带isNew参数时,走if分支渲染对应内容', () => { // 配置mock返回非空字符串,Boolean转换后为true domService.getQueryParamByName.mockReturnValue('true') const wrapper = mount(<TargetComponent />) // 此处写断言,验证if分支的渲染结果符合预期 expect(wrapper.find('.new-page').exists()).toBe(true) }) it('URL不带isNew参数时,走else分支渲染对应内容', () => { // 配置mock返回空串/undefined/null,Boolean转换后为false domService.getQueryParamByName.mockReturnValue('') const wrapper = mount(<TargetComponent />) // 此处写断言,验证else分支的渲染结果符合预期 expect(wrapper.find('.normal-page').exists()).toBe(true) }) })
方案2:用spyOn监听替换单个方法
如果不想整体mock domService模块,只想替换单个方法,可以用jest.spyOn:
import domService from '@/utils/domService' import TargetComponent from './TargetComponent' it('URL带isNew参数时走if分支', () => { // 替换原方法为mock函数 const querySpy = jest.spyOn(domService, 'getQueryParamByName').mockReturnValue('1') const wrapper = mount(<TargetComponent />) // 断言逻辑 expect(wrapper.find('.new-page').exists()).toBe(true) // 执行完恢复原方法,避免污染其他用例 querySpy.mockRestore() })
注意事项:
- 一定要在组件渲染之前配置mock返回值,否则组件render时拿到的还是原方法的返回值,无法触发目标分支
- 注意布尔转换规则:非空字符串(哪怕是
"false")转Boolean都是true,要触发else分支需要返回空字符串、undefined、null这类假值- 多用例场景下记得在
beforeEach中清空mock,或者单用例执行完调用mockRestore恢复原方法,避免用例之间互相干扰
内容的提问来源于stack exchange,提问作者valli
相关产品推荐
相关产品推荐

