如何使用Jest、Enzyme或@testing-library/react选取React组件内的变量
解决方案
首先明确前提:names和surnames是App组件内部的局部变量,默认仅在组件作用域内可访问,测试框架无法直接读取模块私有变量,可通过以下三种方案实现校验:
方案1:使用rewire读取模块私有变量(无需修改业务代码)
rewire是专门用于获取JavaScript模块内部私有变量的工具,实现步骤如下:
- 安装依赖
npm install rewire --save-dev - 修改测试代码
import Adapter from "enzyme-adapter-react-16"; import "@testing-library/jest-dom"; import { configure } from "enzyme"; import rewire from "rewire"; // 用rewire引入App模块 const appModule = rewire("../../block02/ex02/src/App.js"); configure({ adapter: new Adapter() }); describe("b2ex02: Display name and surname side by side", () => { it("Declare two arrays", () => { // 获取模块内部变量,变量不存在时会直接抛出错误,自动完成存在性校验 const names = appModule.__get__("names"); const surnames = appModule.__get__("surnames"); // 校验类型为数组 expect(Array.isArray(names)).toBe(true); expect(Array.isArray(surnames)).toBe(true); // 也可额外校验数组内容符合预期 expect(names).toEqual(["George", "Lewis", "Max", "Charles", "Fernando"]); expect(surnames).toEqual(["Pedrosa", "Rossi", "Crivillé", "Márquez", "Lorenzo"]); }); });
方案2:导出需要校验的变量(无需额外依赖,需修改业务代码)
在App.js末尾添加对应变量的导出语句即可:
// App.js原有代码不变 export { names, surnames }; export default App;
测试代码中直接导入变量校验:
import App, { names, surnames } from "../../block02/ex02/src/App.js"; // 其余代码不变 it("Declare two arrays", () => { expect(Array.isArray(names)).toBe(true); expect(Array.isArray(surnames)).toBe(true); });
方案3:通过渲染行为校验(测试最佳实践,不依赖内部实现)
从测试的设计原则来看,更推荐测试组件的对外表现而非内部实现。当前测试用例集的业务目标是校验姓名并排展示,你可以先实现组件的渲染逻辑:把names和surnames数组的内容一一对应渲染到页面中,之后在测试中校验页面上是否存在对应内容即可间接证明变量存在且格式正确:
it("Declare two arrays", () => { render(<App />); // 校验数组中的所有内容都成功渲染 expect(screen.getByText("George Pedrosa")).toBeInTheDocument(); expect(screen.getByText("Lewis Rossi")).toBeInTheDocument(); // 其余内容校验可自行补充 });
内容的提问来源于stack exchange,提问作者Toni Enguix
相关产品推荐
相关产品推荐

