javascriptreactjsjestjslazy-loadingreact-lazy-load

Testing lazily initialized components with Jest


I am trying to test my lazy initialized component, made with react-lazy-load-image-component using JestJS. Below are my tests:

const viewModel = new VehicleViewModel(vehicleData, {});

const mockOnClick = jest.fn();

const mockStore = configureStore();

let store: MockStore;

beforeEach(() => {
  jest.clearAllMocks();
  store = mockStore(storeInitialState);
});

describe('on component initialization', () => {
  it('renders', () => {
    const { container } = render(
      <Provider store={store}>
        <SearchResult vehicle={viewModel} onClick={mockOnClick} />
      </Provider>
    );
    expect(container).toMatchSnapshot();
  });
});

describe('when the user clicks on the result', () => {
  it('processes an onClick event', () => {
    const { container, getByTestId } = render(
      <Provider store={store}>
        <SearchResult vehicle={viewModel} onClick={mockOnClick} />
      </Provider>
    );
    await waitFor(() => {
      fireEvent.click(getByTestId('search-result'));
    });
    expect(container).toMatchSnapshot();
    expect(mockOnClick).toBeCalled();
  });
});

The component is coded as:

const SearchResult = ({ onClick, vehicle }: SearchResultProps): JSX.Element => {
  const {
    images,
    make,
    model,
    year,
    dealerName,
    city,
    state,
    timeOnMarket,
    mileage,
    price,
  } = vehicle;

  const monthlyPayment = useMonthlyPayment(price);

  return (
    <div className="search-result" data-testid="search-result" onClick={onClick}>
      <style jsx>{styles}</style>
      <div
        className="main-image"
        // replace multiple spaces, if any, with one
        title={`${year || ''} ${make || ''} ${model || ''} image`.replace(/  +/g, ' ')}
      >
        <Carousel images={images} year={year} make={make} model={model} />
        ...
    </div>
  );
};

While the <Carousel /> render is defined as:

  return (
    <LazyLoadComponent>
      <div
        className="carousel-container"
        onMouseEnter={handleMouseEnterEvent}
        onMouseLeave={handleMouseLeaveEvent}
      >
        ...
      </div>
    </LazyLoadComponent>
  );

Without lazy loading, my tests work fine.

Wrapper with lazy loading, my tests fail with: TypeError: Cannot read property 'prototype' of undefined. The error happens on const { container } = render(.... I tried to mock the scroll effect. Did not work for me, yet.

How do I add jest coverage to components using lazy load inside?


Solution

  • I ended up doing the below inside the actual code:

    const TestLasyWrapper = ({ children }: any) => process.env.NODE_ENV !== 'test' ?
      <LazyLoadComponent>{children}</LazyLoadComponent> : 
        <>{children}</>;