reactjs - 模拟 React useRef 或带有酶和玩笑的功能组件内的函数?
问题描述
Codesanbox链接-包括工作组件 Child2.js 和工作测试 Child2.test.js
Child2.js
import React, { useRef } from "react";
export default function Child2() {
const divRef = useRef();
function getDivWidth() {
if (divRef.current) {
console.log(divRef.current);
}
return divRef.current ? divRef.current.offsetWidth : "";
}
function getDivText() {
const divWidth = getDivWidth();
if (divWidth) {
if (divWidth > 100) {
return "ABC";
}
return "123";
}
return "123";
}
return (
<>
<div id="myDiv" ref={divRef}>
{getDivText()}
</div>
<p>Div width is: {getDivWidth()}</p>
</>
);
}
Child2.test.js
import React from "react";
import Enzyme, { shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import Child2 from "../src/Child2";
Enzyme.configure({ adapter: new Adapter() });
it("div text is ABC when div width is more then 100 ", () => {
const wrapper = shallow(<Child2 />);
expect(wrapper.find("#myDiv").exists()).toBe(true);
expect(wrapper.find("#myDiv").text()).toBe("ABC");
});
it("div text is 123 when div width is less then 100 ", () => {
const wrapper = shallow(<Child2 />);
expect(wrapper.find("#myDiv").exists()).toBe(true);
expect(wrapper.find("#myDiv").text()).toBe("123");
});
当我运行测试时,显然 div 的 offsetWidth 为 0,因此我需要找到一种方法来模拟useRef
返回具有宽度的 div 元素或模拟getDivWidth
函数以返回所需的宽度数字。
我怎么能做到这一点?我一直在寻找解决方案,但我被卡住了。有一些带有类组件或使用我没有设法使用的打字稿的示例。
解决方案
您可以使用jest.mock(moduleName, factory, options)和jest.requireActual(moduleName) API 来模拟useRef
除其他之外的钩子。这意味着其他功能和方法react
仍然是原始版本。
例如
index.jsx
:
import React, { useRef } from 'react';
export default function Child2() {
const divRef = useRef();
function getDivWidth() {
if (divRef.current) {
console.log(divRef.current);
}
return divRef.current ? divRef.current.offsetWidth : '';
}
function getDivText() {
const divWidth = getDivWidth();
if (divWidth) {
if (divWidth > 100) {
return 'ABC';
}
return '123';
}
return '123';
}
return (
<>
<div id="myDiv" ref={divRef}>
{getDivText()}
</div>
<p>Div width is: {getDivWidth()}</p>
</>
);
}
index.test.jsx
:
import React, { useRef } from 'react';
import { shallow } from 'enzyme';
import Child2 from './';
jest.mock('react', () => {
const originReact = jest.requireActual('react');
const mUseRef = jest.fn();
return {
...originReact,
useRef: mUseRef,
};
});
describe('61782695', () => {
it('should pass', () => {
const mRef = { current: { offsetWidth: 100 } };
useRef.mockReturnValueOnce(mRef);
const wrapper = shallow(<Child2></Child2>);
expect(wrapper.find('#myDiv').text()).toBe('123');
expect(wrapper.find('p').text()).toBe('Div width is: 100');
});
it('should pass - 2', () => {
const mRef = { current: { offsetWidth: 300 } };
useRef.mockReturnValueOnce(mRef);
const wrapper = shallow(<Child2></Child2>);
expect(wrapper.find('#myDiv').text()).toBe('ABC');
expect(wrapper.find('p').text()).toBe('Div width is: 300');
});
it('should pass - 3', () => {
const mRef = {};
useRef.mockReturnValueOnce(mRef);
const wrapper = shallow(<Child2></Child2>);
expect(wrapper.find('#myDiv').text()).toBe('123');
expect(wrapper.find('p').text()).toBe('Div width is: ');
});
});
覆盖率 100% 的单元测试结果:
PASS stackoverflow/61782695/index.test.jsx (9.755s)
61782695
✓ should pass (111ms)
✓ should pass - 2 (15ms)
✓ should pass - 3 (1ms)
console.log
{ offsetWidth: 100 }
at getDivWidth (stackoverflow/61782695/index.jsx:8:15)
console.log
{ offsetWidth: 100 }
at getDivWidth (stackoverflow/61782695/index.jsx:8:15)
console.log
{ offsetWidth: 300 }
at getDivWidth (stackoverflow/61782695/index.jsx:8:15)
console.log
{ offsetWidth: 300 }
at getDivWidth (stackoverflow/61782695/index.jsx:8:15)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.jsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 10.885s
包版本:
"react": "^16.13.1",
"react-dom": "^16.13.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"jest": "^25.5.4",
"jest-environment-enzyme": "^7.1.2",
"jest-enzyme": "^7.1.2",
推荐阅读
- react-native - 在android应用程序中更新联系人列表的问题
- migration - 将多个“.tfstate”和“.tfvars”文件迁移到“s3”后端
- javascript - EJS:我怎样才能让我的内容占据整个屏幕(例如宽度:100%)?
- regex - 使用 Look Ahead 和 Look Behind Regex 模式时如何替换匹配的第 n 次出现
- r - 如果为 1,则将列转换为逗号分隔列表
- numpy - 如何使用 PyPI 中的二进制文件(不是来自源代码)进行管道安装?
- python - 使用字典中的键从数据框中检索值
- polymer - Cobalt 是否支持 Web 组件(例如 Polymer/lit-element 工作)?
- git - 使用 Gitkraken 将 IntelliJ 连接到 Git
- android - Andrioid 向上滑动即可关闭,无需在回收站视图外切割视图