我有React函数组件,其子组件之一具有ref。引用是通过useRef
创建的。
我想用浅色渲染器测试组件。我必须以某种方式模拟ref以测试其余功能。
我似乎找不到任何方法可以找到该参考并对其进行模拟。我尝试过的事情
通过childs属性访问它。 React并不喜欢这样,因为ref并不是真正的道具
模拟useRef。我尝试了多种方法,但当我的实现使用React.useRef
我看不到其他任何方法来模仿它。在这种情况下是否必须使用mount?
我无法发布真实场景,但我构建了一个小例子
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>);
};
答案 0 :(得分:3)
slideshowp2的解决方案对我不起作用,因此最终使用了另一种方法:
解决方法
import React, { useRef as defaultUseRef } from 'react'
const component = ({ useRef = defaultUseRef }) => {
const ref = useRef(null)
return <RefComponent ref={ref} />
}
const mockUseRef = (obj: any) => () => Object.defineProperty({}, 'current', {
get: () => obj,
set: () => {}
})
// in your test
...
const useRef = mockUseRef({ refFunction: jest.fn() })
render(
<ScanBarcodeView onScan={handleScan} useRef={useRef} />,
)
...
答案 1 :(得分:2)
这是我的单元测试策略,在jest.spyOn
钩上使用useRef
方法监视。
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%的单元测试结果:
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