Jest分支覆盖率始终缺失1个分支(所有组件均存在该问题)
解决React类组件Jest分支覆盖率3/4的困惑
嘿,我之前维护React组件测试时,也碰到过一模一样的问题——所有类组件的分支覆盖率都差一点到100%,当时查了好久才找到根源!
最可能的原因:Babel转译ES6类生成的隐含分支
当你用ES6类写React组件时,Babel默认会生成一个_classCallCheck辅助函数,用来确保你是用new关键字实例化组件的。这个函数里有个if分支,而你永远不会触发它(毕竟没人会把React组件当普通函数调用),这就是那个缺失的分支。
转译后的代码大概长这样:
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
这个if判断就是拖你覆盖率后腿的家伙。
次要可能:PropTypes必填校验的分支
如果你的组件用了PropTypes.string.isRequired这类校验,React在开发环境会生成检查分支——当必填prop未传入时抛出警告。虽然测试环境默认禁用警告,但转译后的代码里这个分支依然存在。如果没测试“不传必填prop”的场景(虽然业务上不该这么做,但为了覆盖率可以补测),也会缺一个分支。不过你说所有组件都有这个问题,这个原因的可能性更低。
解决办法
针对Babel生成的类检查分支
有几种简单的方式可以搞定:
- 修改Babel配置启用loose模式
在你的.babelrc或babel.config.js里添加插件配置,让转译后的代码不再生成这个检查分支:{ "plugins": [ ["@babel/plugin-transform-classes", { "loose": true }] ] } - 在Jest里忽略这个辅助函数
修改jest.config.js,把这类辅助函数排除在覆盖率统计之外:module.exports = { coveragePathIgnorePatterns: [ "/node_modules/", "_classCallCheck.js" ] };
针对PropTypes校验分支
如果是这个原因,可以补一个测试用例(记得禁用警告避免输出干扰):
test("should handle missing required props", () => { // 临时禁用console.error jest.spyOn(console, 'error').mockImplementation(() => {}); render(<Card />); // 验证警告确实被触发了(可选) expect(console.error).toHaveBeenCalled(); // 恢复console.error console.error.mockRestore(); });
根据你描述的“所有组件都有问题”,大概率是Babel生成的类检查分支在搞鬼,试试上面的配置修改,应该就能拿到100%分支覆盖率了!
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

