Create complex renders for react-testing-library
npm install @gpx/render-composerWhen working with Testing Library within a large project often you need to wrap your component
in several providers:
``jsx`
const history = createMemoryHistory();
const locale = 'en';
const user = {name: 'Giorgio'};
render(
);
This can lead to a lot of overhead and is not very flexible.
Render Composer allows you to declare reusable and configurable _wraps_ that define
a single provider. These wraps can then be combined to generate more complex hierarchies.
`jsx
const RouterWrap = wrap((children, {history}) => (
)).defaultData(() => ({
history: createMemoryHistory(),
}));
const IntlWrap = wrap((children, {locale}) => (
)).defaultData({locale: 'en'});
const UserWrap = wrap((children, {user}) => (
)).defaultData({user: {name: 'Giorgio'}});
const appRender = RouterWrap.wraps(IntlWrap)
.wraps(UserWrap)
.withRenderMethod(render);
appRender(
`
With NPM:
`sh`
npm install @gpx/render-composer --save-dev
With Yarn:
`sh`
yarn add @gpx/render-composer --dev
Now simply import it in your tests:
`js
import wrap from '@gpx/render-composer';
// or
var wrap = require('@gpx/render-composer');
`
You can create a wrap with the wrap method:
`jsx`
const Wrap = wrap((children, data) => {children});
data is an empty object by default. You can set some default values with defaultData:
`jsx`
Wrap.defaultData({foo: 'bar'});
If you need the data to be generated every time rather than be static you can also
pass a function to defaultData:
`jsx`
Wrap.defaultData(() => ({foo: Math.random()}));
You can compose the wraps with the wraps method. You can chain as many wraps you want:
`jsx`
WrapA.wraps(WrapB)
.wraps(WrapC)
.wraps(WrapD);
Once you are satisfied with your wrap you can get a render method with withRenderMethod:
`jsx
import {render} from '@testing-library/react';
const renderWrap = Wrap.withRenderMethod(render);
renderWrap(
`
The generated render method will also accept data to overwrite the default values you
defined in your wraps. The data will be returned too:
`jsx
Wrap.defaultData(() => ({foo: 'bar'}));
// This foo will have value 'bar'
const {foo} = renderWrap(
// This foo will have value 'baz'``
const {foo} = renderWrap(
Note that wraps are immutable so that they can be defined in one file and exported and combined.