问题描述
我有一个 React 函数组件,它在它的一个子组件上有一个引用.ref 是通过 useRef
创建的.
I have React function component that has a ref on one of its children. The ref is created via useRef
.
我想用浅渲染器测试组件.我必须以某种方式模拟 ref 以测试其余功能.
I want to test the component with the shallow renderer. I have to somehow mock the ref to test the rest of the functionality.
我似乎找不到任何方法来获得这个参考并嘲笑它.我尝试过的东西
I can't seem to find any way to get to this ref and mock it. Things I have tried
通过 childs 属性访问它.React 不喜欢那样,因为 ref 并不是真正的道具
Accessing it via the childs property. React does not like that, since ref is not really a props
模拟 useRef.我尝试了多种方法,但只有在我的实现使用 React.useRef
Mocking useRef. I tried multiple ways and could only get it to work with a spy when my implementation used React.useRef
我看不到任何其他方法可以让裁判嘲笑它.在这种情况下我必须使用 mount 吗?
I can't see any other way to get to the ref to mock it. Do I have to use mount in this case?
我无法发布真实场景,但我构建了一个小例子
I can't post the real scenario, but I have constructed a small example
it('should test', () => {
const mock = jest.fn();
const component = shallow(<Comp onHandle={mock}/>);
// @ts-ignore
component.find('button').invoke('onClick')();
expect(mock).toHaveBeenCalled();
});
const Comp = ({onHandle}: any) => {
const ref = useRef(null);
const handleClick = () => {
if (!ref.current) return;
onHandle();
};
return (<button ref={ref} onClick={handleClick}>test</button>);
};
推荐答案
这是我的单元测试策略,在 useRef
钩子上使用 jest.spyOn
方法 spy.
Here is my unit test strategy, use jest.spyOn
method spy on the useRef
hook.
index.tsx
:
import React from 'react';
export const Comp = ({ onHandle }: any) => {
const ref = React.useRef(null);
const handleClick = () => {
if (!ref.current) return;
onHandle();
};
return (
<button ref={ref} onClick={handleClick}>
test
</button>
);
};
index.spec.tsx
:
import React from 'react';
import { shallow } from 'enzyme';
import { Comp } from './';
describe('Comp', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should do nothing if ref does not exist', () => {
const useRefSpy = jest.spyOn(React, 'useRef').mockReturnValueOnce({ current: null });
const component = shallow(<Comp></Comp>);
component.find('button').simulate('click');
expect(useRefSpy).toBeCalledWith(null);
});
it('should handle click', () => {
const useRefSpy = jest.spyOn(React, 'useRef').mockReturnValueOnce({ current: document.createElement('button') });
const mock = jest.fn();
const component = shallow(<Comp onHandle={mock}></Comp>);
component.find('button').simulate('click');
expect(useRefSpy).toBeCalledWith(null);
expect(mock).toBeCalledTimes(1);
});
});
100% 覆盖率的单元测试结果:
Unit test result with 100% coverage:
PASS src/stackoverflow/57805917/index.spec.tsx
Comp
✓ should do nothing if ref does not exist (16ms)
✓ should handle click (3ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 4.787s, estimated 11s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57805917
这篇关于在 React 函数组件中模拟 refs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!