Skip to content

Instantly share code, notes, and snippets.

@Jyrno42
Last active November 12, 2019 14:58
Show Gist options
  • Save Jyrno42/78d65f5e98a1cb925957249a450de2f3 to your computer and use it in GitHub Desktop.
Save Jyrno42/78d65f5e98a1cb925957249a450de2f3 to your computer and use it in GitHub Desktop.
Testing useImperativeHandle with react-test-renderer. Is there a more elegant way than this?
import { forwardRef, useImperativeHandle } from 'react';
const Example = (_, ref) => {
useImperativeHandle(
ref,
() => ({
methodFromUseImperativeHandle: () => true
}),
[]
);
return null;
};
export default forwardRef(Example);
import React, { useRef } from 'react';
import renderer, { act } from 'react-test-renderer';
import Example from './Example';
import unsafeGetTestingRef from './testing-ref';
test('test which calls methods on ref (for useImperativeHandle)', async () => {
const UsesRef = () => {
const ref = useRef();
return <Example ref={ref} />;
};
let tree;
await act(async () => {
tree = renderer.create(<UsesRef key="root" />);
return tree;
});
const ref = unsafeGetTestingRef(tree, Example);
expect(ref.current).not.toBeNull();
expect(ref.current).toMatchObject({
methodFromUseImperativeHandle: expect.any(Function)
});
expect(ref.current.methodFromUseImperativeHandle()).toBe(true);
});
const unsafeGetTestingRef = (tree, component) => {
// Unsafe way to get access to a ref property. Uses internal _fiber property of a ReactTestingInstance since AFAIK react-test-renderer does not expose refs in any other way
const node = tree.root.findByType(component);
expect(node).not.toBeNull();
expect(node._fiber).not.toBeNull();
expect(node._fiber).not.toBeUndefined();
const ref = node._fiber.ref;
expect(ref).not.toBeNull();
expect(ref).not.toBeUndefined();
return ref;
};
export default unsafeGetTestingRef;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment