Narwhals Playing Mahjong

    TypeScript icon, indicating that this package has built-in type declarations

    3.2.0 • Public • Published

    Render Composer


    Create complex renders for react-testing-library

    The problem

    When working with Testing Library within a large project often you need to wrap your component in several providers:

    const history = createMemoryHistory();
    const locale = 'en';
    const user = {name: 'Giorgio'};
      <Router history={history}>
        <IntlProvider locale={locale}>
          <UserContext.Provider value={user}>
            <MyComponent />

    This can lead to a lot of overhead and is not very flexible.

    The solution

    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.

    const RouterWrap = wrap((children, {history}) => (
      <Router history={history}>{children}</Router>
    )).defaultData(() => ({
      history: createMemoryHistory(),
    const IntlWrap = wrap((children, {locale}) => (
      <IntlProvider locale={locale}>{children}</IntlProvider>
    )).defaultData({locale: 'en'});
    const UserWrap = wrap((children, {user}) => (
      <UserContext.Provider value={user}>{children}</UserContext.Provider>
    )).defaultData({user: {name: 'Giorgio'}});
    const appRender = RouterWrap.wraps(IntlWrap)
    appRender(<MyComponent />);


    With NPM:

    npm install @gpx/render-composer --save-dev

    With Yarn:

    yarn add @gpx/render-composer --dev

    Now simply import it in your tests:

    import wrap from '@gpx/render-composer';
    // or
    var wrap = require('@gpx/render-composer');


    You can create a wrap with the wrap method:

    const Wrap = wrap((children, data) => <div>{children}</div>);

    data is an empty object by default. You can set some default values with defaultData:

    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:

    Wrap.defaultData(() => ({foo: Math.random()}));

    You can compose the wraps with the wraps method. You can chain as many wraps you want:


    Once you are satisfied with your wrap you can get a render method with withRenderMethod:

    import {render} from '@testing-library/react';
    const renderWrap = Wrap.withRenderMethod(render);
    renderWrap(<MyComponent />);

    The generated render method will also accept data to overwrite the default values you defined in your wraps. The data will be returned too:

    Wrap.defaultData(() => ({foo: 'bar'}));
    // This `foo` will have value `'bar'`
    const {foo} = renderWrap(<MyComponent />);
    // This `foo` will have value `'baz'`
    const {foo} = renderWrap(<MyComponent />, {foo: 'baz'});

    Note that wraps are immutable so that they can be defined in one file and exported and combined.




    npm i @gpx/render-composer

    DownloadsWeekly Downloads






    Unpacked Size

    23 kB

    Total Files


    Last publish


    • gpx