Jest未覆盖const声明函数问题求助
Jest 代码覆盖率问题:Portal 函数未被覆盖
我正在用 Jest 提升代码覆盖率,目前测试运行成功,但语句覆盖率仅为75%,排查发现以下Portal函数未被覆盖:
index.tsx
import * as React from "react"; import * as ReactDom from "react-dom"; import './index.css'; import App from './app'; import { Provider } from "react-redux"; import { setupStore } from "./store"; const store = setupStore(); const Portal = () => { return ( <Provider store={store}> <App /> </Provider> ); }; ReactDom.render(<Portal />, document.getElementById("root"));
index.test.tsx
import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "react-redux"; import { setupStore } from "../store"; jest.mock("react-dom", () => ({ render: jest.fn() })); jest.mock('../app'); const store = setupStore(); describe('Test index.js', () => { it("Should render app without crashing", () => { const div = document.createElement("div"); div.id = "root"; document.body.appendChild(div); require('../index'); // expect(ReactDOM.render).toHaveBeenCalledWith( // <Portal />, // document.getElementById("root") // ); }); });
解决方案
问题根源在于你用jest.mock完全替换了react-dom的render方法,变成了空的jest函数,它不会真正去渲染<Portal />组件,自然不会执行Portal的函数体代码。
步骤1:导出Portal组件
先修改index.tsx,把Portal导出,方便测试中直接引用:
// index.tsx export const Portal = () => { return ( <Provider store={store}> <App /> </Provider> ); };
步骤2:修改测试代码,触发Portal渲染
改用@testing-library/react来渲染组件(或者直接调用Portal函数),确保其代码被执行:
// index.test.tsx import React from "react"; import { render } from '@testing-library/react'; import { Portal } from '../index'; import App from '../app'; jest.mock('../app'); describe('Test index.tsx', () => { it("Should render Portal component", () => { // 直接渲染Portal组件,触发其函数体执行 render(<Portal />); // 验证App组件被调用(因为已经mock了App) expect(App).toHaveBeenCalled(); }); it("Should mount app to root element", () => { const div = document.createElement("div"); div.id = "root"; document.body.appendChild(div); // 用spyOn代替全量mock,保留原render的逻辑 const renderSpy = jest.spyOn(ReactDOM, 'render'); require('../index'); expect(renderSpy).toHaveBeenCalled(); renderSpy.mockRestore(); }); });
这样修改后,Portal函数的代码会被执行,就能把覆盖率拉满了。
内容的提问来源于stack exchange,提问作者Bhushan Gadekar
相关产品推荐
相关产品推荐

