I would like to test the following class, which uses the React.createRef
api.
A quick search didn't reveal any any examples of doing this though. Has anyone had success? How would I go about mocking the ref?
Ideally I'd like to use shallow
.
class Main extends React.Component<Props, State> {
constructor(props) {
super(props);
this.state = {
contentY: 0,
};
this.domRef = React.createRef();
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
handleScroll();
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll = () => {
const el = this.domRef.current;
const contentY = el.offsetTop;
this.setState({ contentY });
};
render() {
return (
<Wrapper innerRef={this.domRef}>
<MainRender contentY={this.state.contentY} {...this.props} />
</Wrapper>
);
}
}
Update
So I can test this using callback refs as follows
setRef = (ref) => {
this.domRef = ref;
}
handleScroll = () => {
const el = this.domRef;
if (el) {
const contentY = el.offsetTop;
this.setState({ contentY });
}
};
render() {
return (
<Wrapper ref={this.setRef}>
<MainRender contentY={this.state.contentY} {...this.props} />
</Wrapper>
);
}
}
Then testing something like
it("adds an event listener and sets currentY to offsetTop", () => {
window.addEventListener = jest.fn();
const component = shallow(<ScrollLis />)
const mockRef = { offsetTop: 100 };
component.instance().setRef(mockRef);
component.instance().componentDidMount();
expect(window.addEventListener).toBeCalled();
component.update();
const mainRender = component.find(MainRender);
expect(mainRender.props().contentY).toBe(mockRef.offsetTop);
});
If you want mimic real-world user interactions, the React Testing Library is the way to go because you can do the same with fireEvent functions. Meanwhile, Enzyme is better suited to situations where you have to match the state of React or some other function with state.
Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.
There's no specific routine for refs to be tested. A ref is just an object with current
key.
In case it's accessed early in componentDidMount
, lifecycle hooks need to be disabled for testing. A component should be tested that it initially has a ref, then it can be mocked
const wrapper = shallow(<Comp/>, { disableLifecycleMethods: true });
expect(wrapper.instance().domRef).toEqual({ current: null });
wrapper.instance().domRef.current = mockRef;
wrapper.instance().componentDidMount();
Since a ref is passed to another component as a prop, it can be tested that it was provided with correct ref:
expect(wrapper.find(Wrapper).dive().props().innerRef).toBe(wrapper.instance().domRef);
Then in Wrapper
test can be tested that ref current
key is assigned with correct object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With