在 React 函数组件中模拟 refs [英] Mocking refs in React function component

查看:14
本文介绍了在 React 函数组件中模拟 refs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆