Open
Description
react-hooks-testing-library
version:8.0.1
react
version:16.13.1
react-dom
version:16.13.1
React Magnetic DI is a library that allows dependency injection in React components and functions for testing purposes.
It looks like the wrappers for renderHook
and render
(from @testing-library/react
) behave quite differently. While render
works with custom providers other than the React context, somehow renderHook
fails to do so.
renderHook
does not work when a React Magnetic DI provider is used as a wrapper.
Reproducible example
import React, { type ReactElement, type ComponentType, type ReactNode } from 'react';
import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { injectable, di, DiProvider, type Dependency } from 'react-magnetic-di';
const createRtlDiWrapper =
(use: Dependency[]): ComponentType<{ children: ReactNode }> =>
(props: { children: ReactNode }) =>
<DiProvider use={use}>{props.children}</DiProvider>;
const renderHookWithDi = <TProps, TResult>(
callback: (props: TProps) => TResult,
dependencies: Dependency[] = [],
) =>
renderHook<TProps, TResult>(callback, {
wrapper: createRtlDiWrapper(dependencies) as unknown as ComponentType<TProps>,
});
const renderWithDi = (element: ReactElement, dependencies: Dependency[] = []) =>
render(element, {
wrapper: createRtlDiWrapper(dependencies),
});
const exampleDependency = () => 1;
describe('renderHook vs render', () => {
const deps = [injectable(exampleDependency, () => 2)];
it('should inject dependency using renderHook (but fails)', () => {
const useExample = () => {
di(exampleDependency);
return { value: exampleDependency() };
};
const { result } = renderHookWithDi(() => useExample(), deps);
expect(result.current).toEqual({ value: 2 });
});
it('should inject dependency using render', () => {
const Example = () => {
di(exampleDependency);
return <span>{exampleDependency()}</span>;
};
const { asFragment } = renderWithDi(<Example />, deps);
expect(asFragment()).toMatchInlineSnapshot(`
<span>
2
</span>
`);
});
});
Expectation
Both tests would pass as the dependency should be properly injected using the DI wrapper.
Actual Behaviour
Only the second test, using render
, passes, as the dependency is properly injected. The first one fails because it uses the actual implementation instead.