2

我想为我的 React-native 应用程序编写测试。我的父组件将执行子组件中的方法。我的子组件正在使用 Hooks forwardRef、useImperativeHandle、Ref 如下所示

childs.tsx

export interface RefChild {
    toggle: () => void,
    close: () => void
}

const Child = forwardRef((props: ChildProps, ref: Ref<RefChild>) => {
    const [isVisible, setIsVisible] = useState(false);
    useImperativeHandle(ref, () => ({ toggle, close }));

    const toggle = () => {
        setIsVisible(!isVisible);
    }

    const close = () => {
        setIsVisible(false)
    }

    return (...mycomponent)
}

我的父组件正在捕获'ref'调用

ref={(el: RefChild) => childRef.current = el}

这使我可以从父级中调用“切换”和“关闭”方法。现在,我不明白如何在我的测试中做同样的事情

我的父母-test.tsx:

describe('Parent', () => {
    let wrapper: ShallowWrapper;
    let props: any;
    beforeEach(() => {
        props = createTestProps({});
        wrapper = shallow(<Parent {...props} />);
    });

//this is what I am currently trying to do, but not working
//test 1 (not working)
    it("useRef child", () => {
        const useRefSpy = jest.spyOn(React, 'useRef').mockReturnValueOnce({ current: <Child/> });
        expect(useRefSpy).toBeCalled();
        useRefSpy.current.toggle();
    })

//test 2 (not working)
    it("useRef child2", () => {
        const ref = {
            current: {
                toggle: jest.fn(),
                close: jest.fn()
            }
        }

        ref.current.toggle();
    })

//test 3 (not working)
    it("useRef child3", () => {
        wrapper.instance().childref.current.toggle(); //failing as functional components don't have instance
    })
})

我的 React 和 RN 版本是:

    "react": "16.13.1",
    "react-native": "0.63.3"

谁能解释我应该如何实现这一目标?

4

1 回答 1

0

正如您在问题中提到的那样instancefunctional组件中没有,我认为有一种更好的方法来处理toggle和处理close函数,方法是为它们中的每parent component一个使用布尔值prop并监听这个值的变化,如下所示:

您在父组件中有一个称为isClose设置为 false 的状态,然后在子组件中您使用如下内容:

useEffect(() => {
   if(isClose){
     //call close function
     close()
   }
}, [isClose])

但是顺便说一下,在您当前的设置中,我认为您需要useRef像这样模拟钩子:


const useRefSpy = jest
  .spyOn(React, "useRef")
  .mockReturnValueOnce(() => ({ current: <Child /> }));
于 2020-12-24T11:50:09.097 回答