Jest mock not working with React Testing Library

7.2k Views Asked by At

I am using @testing-library/react for testing UI components. Cannot get jest mock working.

It seems it cannot mock the implementation of the exported function getDomElement but actual implementation is called.

Implementation of Table.test.js

describe('Table', () => {
  jest.mock('../../../../commonHelpers/getDomElement.js', () => {});

  it('it renders columns', () => {
    render(
      <ThemeProvider>
        <Table
          columns={columns}
          data={data}         
        />
      </ThemeProvider>,
    );
  })
})

Implementation of Table.js

import React, { useEffect } from 'react';
import PropTypes from 'prop-types';

import {
  useTable,
  useSortBy,
  useBlockLayout,
  useResizeColumns,
  usePagination,
} from 'react-table';

import { TableStyled as Table, TableContainer } from './styled';
import Pagination from './Pagination';
import Head from './Head';
import Body from './Body';
import TableContext from './TableContext';

const Table = ({
  columns,
  data,
  onChangeSort,
  fetchData,
  pageCount: calculatedPageCount,
  initialPageSize,
}) => {
  const tableInstance = useTable(
    {
      columns,
      data,
      manualSortBy: true,
      disableSortRemove: false,
      manualPagination: true,
      pageCount: calculatedPageCount,
      initialState: { pageIndex: 0, pageSize: initialPageSize },
    },
    useSortBy,
    useBlockLayout,
    useResizeColumns,
    usePagination,
  );

  const {
    getTableProps,
    state: { pageIndex, pageSize },
  } = tableInstance;


  useEffect(() => {
    fetchData({ pageIndex, pageSize });
  }, [fetchData, pageIndex, pageSize]);

  return (
    <TableContext.Provider value={tableInstance}>
      <TableContainer>
        <Table {...getTableProps()}>
          <Head onChangeSort={onChangeSort} />
          <Body />
        </Table>
      </TableContainer>
      <Pagination />
    </TableContext.Provider>
  );
};

Table.propTypes = {
  columns: PropTypes.array,
  data: PropTypes.array,
  onChangeSort: PropTypes.func,
  fetchData: PropTypes.func,
  pageCount: PropTypes.number,
  initialPageSize: PropTypes.number,
};

export default Table;

Implementation of getDomElement.js which returns the dom element by given id.

export default function getDomElement(id) {
  return document.getElementById(id);
}

Test results in:

const width = getDomElement('project-list').clientWidth;

TypeError: Cannot read property 'clientWidth' of null

3

There are 3 best solutions below

4
On

Try this:

import * as myModule from '../../../../commonHelpers/getDomElement';
describe('Table', () => {
  jest.spyOn(myModule, "getDomElement").mockImplementation(() => {});
  it('it renders columns', () => {
    render(
      <ThemeProvider>
        <Table
          columns={columns}
          data={data}         
        />
      </ThemeProvider>,
    );
  })
})
0
On

Doing following two thing, got it working for me.

  1. Adding __esModule:true fixed this issue for me.

    jest.mock('module',()=>({ __esModule: true, default: jest.fn() }));

  2. Moving the mocking part before the describe. (Just after the imports.)

    //moving it to before the describe -> jest.mock(...); describe('', ...);

Hope this helps somebody.

0
On

I know this was 3 years ago, but if anyone is still having the same problem (with Typescript) I was able to fix it.

So the problem happens when you add import '@testing-library/react-native/extend-expect'; to setupJest file along with a jest.mock.

According to the documentation, you can use setupFilesAfterEnv as an alternative for the import. Add the bellow to your package.json:

"setupFilesAfterEnv": ["@testing-library/react-native/extend-expect"]

Now it'll work but Typescript is still complaining about some expect functions. Now we'll trick typescript into thinking everything is ok.

Create a second file called setupTestingLibrary.ts and add the import there. Typescript will think this file is being used and will read the types.

In my case, the setupJest.ts file is in root directory. You should create the second file in the same directory as setupJest, but if that doesn't work try creating both at root dir.

Hope it helps.