Skip to content

Instantly share code, notes, and snippets.

@dfbaskin
Created September 14, 2021 20:11
Show Gist options
  • Save dfbaskin/427c5a7b91f88dfa28ae7677362bd04c to your computer and use it in GitHub Desktop.
Save dfbaskin/427c5a7b91f88dfa28ae7677362bd04c to your computer and use it in GitHub Desktop.
useOverrides hook to replace component hooks, elements, whatever for testing and Storybook.
import { render } from '@testing-library/react';
import { screen } from '@testing-library/dom';
import { useOverrides } from '../useOverrides';
import '@testing-library/jest-dom';
function useFakeTranslation(textId: string) {
return `${textId.toUpperCase()}-XLATED`;
}
function TestIcon() {
return <span data-testid="icon">πŸ˜ƒ</span>;
}
const defaults = {
TestIcon,
useFakeTranslation,
};
interface Props {
textId: string;
__overrides__?: Partial<typeof defaults>;
}
function TestComponent(props: Props) {
const { textId } = props;
const { TestIcon, useFakeTranslation } = useOverrides(props, defaults);
const text = useFakeTranslation(textId);
return (
<div>
<TestIcon />
<span data-testid="text">{text}</span>
</div>
);
}
describe('use overrides', () => {
test('should render with defaults', () => {
render(<TestComponent textId="abc" />);
expect(screen.getByTestId('icon')).toHaveTextContent('πŸ˜ƒ');
expect(screen.getByTestId('text')).toHaveTextContent('ABC-XLATED');
});
test('should override test icon', () => {
const __overrides__ = {
TestIcon: () => <span data-testid="icon">πŸ™ƒ</span>,
};
render(<TestComponent textId="abc" __overrides__={__overrides__} />);
expect(screen.getByTestId('icon')).toHaveTextContent('πŸ™ƒ');
expect(screen.getByTestId('text')).toHaveTextContent('ABC-XLATED');
});
test('should override translated text hook', () => {
const __overrides__ = {
useFakeTranslation: (textId: string) =>
`${textId.toLowerCase()}-override`,
};
render(<TestComponent textId="XYZ" __overrides__={__overrides__} />);
expect(screen.getByTestId('icon')).toHaveTextContent('πŸ˜ƒ');
expect(screen.getByTestId('text')).toHaveTextContent('xyz-override');
});
test('should override both', () => {
const __overrides__ = {
TestIcon: () => <span data-testid="icon">πŸ™ƒ</span>,
useFakeTranslation: (textId: string) =>
`${textId.toLowerCase()}-override`,
};
render(<TestComponent textId="lMnOp" __overrides__={__overrides__} />);
expect(screen.getByTestId('icon')).toHaveTextContent('πŸ™ƒ');
expect(screen.getByTestId('text')).toHaveTextContent('lmnop-override');
});
});
export interface PropsWithOverrides<T extends {}> {
__overrides__?: Partial<T>;
}
export function useOverrides<T extends {}>(
props: PropsWithOverrides<T>,
defaults: T
) {
return props.__overrides__
? {
...defaults,
...props.__overrides__,
}
: defaults;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment