jest-mock-external-components

Mock external React components with jest

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
jest-mock-external-components
4153.0.14 years ago6 years agoMinified + gzip package size for jest-mock-external-components in KB

Readme

Easy automock your external react components

Do you like write component tests? Do you like react-test-renderer more than shallow renderer? Do you feel sometimes that it would be great to combine both shallow renderer and react-test-renderer to prevent rendering inner components? Do you feel headcache when writing tests for something like styled-components ? Are you bored to write numerous ``jest.mock()`` calls to mock your component?
If the answer for any of these questions is "Yes" then you come to the right place.
Much often, you want to mock/don't render external components. Almost always these external components are being imported through import statement ``import A from "./a"``. And very often you want to full render the inner (helpers or styled) components:
import Button from "./Button";
import AnotherComp from "./AnotherComp";

const SomeText = () => <h1>SomeText</h1>

const SomeLabel = styled.label`
    font-size: 0.8em;
`;

const MyButton = styled(Button)`
    font-size: 2em;
`

const Component = () =>
<div>
    <SomeText />
    <AnotherComp />
    <SomeLabel>Label</SomeLabel>
    <MyButton>Button</MyButton>
</div>

Here you probably want to fully render ``SomeText` , `SomeLabel` and partially `MyButton` (render styles but don't render `Button` itself). `AnotherComp`` should remain non-rendered (so it's internals won't affect the component test).
This is not achievable by standard react-test-renderer, it will give you snapshot similar to this:
.SomeLabelCss {}

.MyButtonCss {}

// Shouldn't be here
.ButtonCss {}

// Shouldn't be here
.AnotherCompCss {}

<div>
    <h1>SomeText</h1>
    // Shouldn't be here
    <div className="AnotherCompCss">AnotherComp internals</div>
    <label className="SomeLabelCss">Label</label>
    // Shouldn't be here
    <button className="MyButtonCss ButtonCss">Button</button>
</div>

Shallow renderer also won't give you desired result:
// No styles since it doesn't unwrap styled-component HOC

<div>
    // Didn't unwrap the internal component
    <SomeText />
    <AnotherComp />
    // Didn't unwrap the internal component
    <SomeLabel>Label</SomeLabel>
    // Didn't unwrap the internal component
    <MyButton>Button</MyButton>
</div>

Ideally, you want this snapshot:
.SomeLabelCss {}

.MyButtonCss {}

<div>
    <h1>SomeText></h1>
    // External component shouldn't be rendered
    <AnotherComp />
    <label className="SomeLabelCss">Label</label>
    // Unwrap styled HOC but don't render further. Button already has dedicated test
    <Button className="MyButtonCss">Button</Button>
</div>

This is achievable by mocking components using ``jest.mock()`` but this is boring and repetetive task, especially when you have to mock many components:
jest.mock("../AnotherComp", () => "AnotherComp");
jest.mock("../Button", () => "Button");
jest.mock("../SomeComp", () => ({ SomeComp: "SomeComp" })); // very ugly for named exports
// etc...

Finally, now you can just use ``jest-mock-external-components``:
import Component from "../mycomponent";
import { mockExternalComponents } from "jest-mock-external-components";
mockExteralComponents(Component);
// will automatically mock <Button /> and <AnotherComp />

// Use react-test-renderer
const t = create(<Component />);
expect(t.toJSON()).toMatchSnapshot();

and it will you give the snapshot which you want with mocked external dependencies and fully-rendered internal components! and it's not shallow, so the lifecycle, refs etc will continue to work.

Installation and setup

``yarn add jest-mock-external-components --dev`` or ``npm install jest-mock-external-components --save-dev``
Add to your ``.babelrc` / `.babelrc.js` / `babel.config.js``
plugins: [
    "jest-mock-external-components/babel",
]