Mocking refs in React function component

前端 未结 2 1476
情深已故
情深已故 2021-01-13 15:58

I have React function component that has a ref on one of its children. The ref is created via useRef.

I want to test the component with the shallow ren

相关标签:
2条回答
  • 2021-01-13 16:24

    The solution from slideshowp2 didn't work for me, so ended up using a different approach:

    Worked around it by

    1. Introduce a useRef optional prop and by default use react's one
    import React, { useRef as defaultUseRef } from 'react'
    const component = ({ useRef = defaultUseRef }) => {
      const ref = useRef(null)
      return <RefComponent ref={ref} />
    }
    
    1. in test mock useRef
    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} />,
        )
    ...
    
    0 讨论(0)
  • 2021-01-13 16:36

    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);
      });
    });
    

    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
    

    Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57805917

    0 讨论(0)
提交回复
热议问题