adam sisk

May 30, 2022

Mock a React Component Library with Jest

Create __mocks__ directory adjacent to node_modules with an empty react-bootstrap.js file

node_modules/
__mocks__/
  react-bootstrap.js
src/
  app.js
  index.html


using jest.mock, mock the functionality of the component

App.test.js
/** @jest-environment jsdom */
import React from 'react';
import '@testing-library/jest-dom';
import { render } from '@testing-library/react';
import { App } from './App';

const Carousel = ({ children }) => (
  <>
    <div data-testid='carousel'>{children}</div>
  </>
);
const Item = ({ children }) => (
  <>
    <div data-testid='item'>{children}</div>
  </>
);
const Caption = ({ children }) => (
  <>
    <div data-testid='caption'>{children}</div>
  </>
);
Carousel.Item = Item;
Carousel.Caption = Caption;

jest.mock('react-bootstrap', () => ({ Carousel }));

it('should render', () => {
  const { baseElement } = render(<App />);

  expect(baseElement).toBeInTheDocument();
});

it('should render a carousel', () => {
  const { getByTestId } = render(<App />);

  expect(getByTestId('carousel')).toBeInTheDocument();
});

it('should render a carousel with 4 items', () => {
  const { getAllByTestId } = render(<App />);

  expect(getAllByTestId('item').length).toBe(4);
});

it('each carousel item should have a caption', () => {
  const { getAllByTestId } = render(<App />);

  expect(getAllByTestId('caption').length).toBe(4);
});



App.js (for reference)
import React from 'react';
import { Carousel } from 'react-bootstrap';

function App() {
  return (
    <Carousel>
      {cats.map((cat) => (
        <Carousel.Item key={cat.name}>
          <img className='w-100' src={cat.imgUrl} alt={cat.name} />
          <Carousel.Caption>
            <h3>{cat.name}</h3>
            <p>{cat.about}</p>
          </Carousel.Caption>
        </Carousel.Item>
      ))}
    </Carousel>
  );
}

export { App };

const cats = [
  {
    imgUrl: 'https://source.unsplash.com/FbhNdD1ow2g',
    name: 'Dopey',
    about: 'Just here for the snacks',
  },
  {
    imgUrl: 'https://source.unsplash.com/IZaXUf6sLiA',
    name: 'Grumpy',
    about: "Tired of Dopey's snacking",
  },
  {
    imgUrl: 'https://source.unsplash.com/LcAZcVWsCIo',
    name: 'Sleepy',
    about: 'ZzzzzzZZzzzz...',
  },
  {
    imgUrl: 'https://source.unsplash.com/HrMD7MngiBE',
    name: 'Sneezy',
    about: 'Ah-choo!',
  },
];









I'm writing technical curriculum for a Front-end Development online course, and recently ran into a blocking problem.

This particular course is on the use of CSS Frameworks and React Component libraries in a React app. The platform has a built-in browser-based IDE, complete with a Jest test suite to provide instant feedback. However there's only 1 problem. The test suite is a standalone docker image, and has no awareness of what dependencies have been added to the React app. The tests can import files form the app (i.e., src/App.js) but can not access any third party libraries/dependencies.

Those libraries can be added to the test image, but this is a lengthy process and not a scalable solution. Each lesson could have multiple different dependencies added, and only used once or twice total. It didn't make sense to add those libraries to the image.

Using mocks I could manually implement the functionality of the dependency that the students would be utilizing.