-
Notifications
You must be signed in to change notification settings - Fork 232
Open
Labels
bugSomething isn't workingSomething isn't working
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.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
andyl-ioki commentedon Mar 15, 2024
@haskellcamargo
I know you opened this ticket a long while ago, but maybe it will still help others.
Your code contains a mistake:
renderHook
generics are first the type for the result and then followed by the type of the props. As a refactoring result your type assertion of the wrapper should not be necessary anymore. Maybe it also unreveals some other bug in your code? 🤔