admin管理员组

文章数量:1289901

I am using @testing-library/react for testing UI ponents. 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('../../../../monHelpers/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

I am using @testing-library/react for testing UI ponents. 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('../../../../monHelpers/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

Share Improve this question edited Oct 13, 2020 at 7:40 anmatika asked Oct 9, 2020 at 7:07 anmatikaanmatika 1,7016 gold badges23 silver badges30 bronze badges 3
  • Please include some more info. – Sarun UK Commented Oct 9, 2020 at 11:48
  • Added Table and getDomElement implementations. – anmatika Commented Oct 13, 2020 at 7:45
  • @RootNode I'm facing the same issue. My jest.mock only works when it is in jestsetup.js. When I move the same to a test file it doesn't work. It only started to happen when I moved to @testing-library/react – Vishal Sharma Commented Mar 24, 2021 at 6:53
Add a ment  | 

3 Answers 3

Reset to default 4

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.

Try this:

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

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 plaining 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.

本文标签: javascriptJest mock not working with React Testing LibraryStack Overflow