如何在Jest中为toThrow语句获取测试覆盖率且不导致测试失败
解决React组件错误抛出代码的测试覆盖率问题
我明白你遇到的困境了——Jest覆盖率报告里那行throw new Error('invalid')始终没被覆盖,用.not.toThrow()碰不到这个分支,尝试Enzyme的时候还卡壳了对吧?别着急,我来给你捋清楚怎么调整测试,既能覆盖到这行代码,又能让测试顺利通过。
首先得抓住核心问题:当你直接写const wrapper = shallow( <MyComponent invalid /> )时,组件会在这一行立刻执行构造函数并抛出错误,测试还没走到断言环节就直接失败了,自然没法覆盖到那行代码。所以关键是把组件的实例化逻辑包裹在一个函数里,让Jest可以捕获这个错误,而不是让错误直接中断测试。
给你看正确的测试代码:
it('should throw an error when provided with invalid prop', () => { // 把组件的渲染逻辑封装成一个函数 const createInvalidComponent = () => { shallow(<MyComponent invalid />); }; // 用Jest的toThrow断言这个函数会抛出指定错误 expect(createInvalidComponent).toThrow('invalid'); });
为什么这样就能解决问题?
- 把
shallow渲染放在函数里,Jest调用这个函数时会自动捕获抛出的错误,不会让测试直接崩溃。 - 这个断言既验证了你的错误抛出逻辑是正确的,又能让覆盖率工具检测到
throw那行代码已经被执行过。
另外补充两个小提示:
- 你之前尝试的
wrapper.instance()在这里没用,因为组件在构造函数抛出错误时根本没完成实例化,根本拿不到实例对象。 - 记得搭配一个测试正常props的用例,比如:
这样两个用例就能覆盖组件的所有分支,覆盖率就拉满了。it('should render without throwing when props are valid', () => { expect(() => shallow(<MyComponent />)).not.toThrow(); });
内容的提问来源于stack exchange,提问作者galki
相关产品推荐
相关产品推荐

