我想为我的React原生应用程序编写测试。我的父组件将执行子组件中的方法。我的子组件正在使用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}
这允许我从Parent中调用"toggle"one_answers"close"方法。现在,我不明白如何在我的测试中做同样的事情
我的父母测试.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"
有人能解释一下我该如何做到这一点吗?
正如您在问题中提到的,functional
组件中没有instance
,我认为有一种更好的方法可以处理parent component
中的toggle
和close
函数,对它们分别使用布尔prop
,并像这样侦听该值的变化:
父组件isClose
中有一个状态设置为false,然后在子组件中使用类似的东西:
useEffect(() => {
if(isClose){
//call close function
close()
}
}, [isClose])
但顺便说一句,在你目前的设置中,我认为你需要模拟useRef
挂钩,比如这样:
const useRefSpy = jest
.spyOn(React, "useRef")
.mockReturnValueOnce(() => ({ current: <Child /> }));