7
votes

I have a CRA app and am trying to the use the manual mocks feature of Jest, but my manual mocks does not seem to be applied.

I use a base url of src (by setting it in tsconfig.json). Simplified, I have and have a file structure of

src/
|- components/
|-- Foo/
|--- index.js
|--- Foo.jsx
|- App.js
|- App.test.js

where App.js uses import Foo from "components/Foo". In App.test.js I want Foo to be mocked (it's computationally heavy and tested in unit tests). So in my test I added jest.mock("components/Foo") and in my desperation added several __mocks__ folders like

__mocks__
|- components\
|-- Foo.jsx
src/
|- __mocks__/
|-- components/
|--- Foo.jsx
|- components/
|-- Foo/
|--- __mocks__
|---- Foo.js
|--- index.js
|--- Foo.jsx
|- App.js
|- App.test.js

where each manual mock contains

console.log("Mock imported");

export default function MyMock(){
  console.log("Mock used");
  return <p />;
}

However, when running the tests no there are no console printouts from the mock and although Foo is assigned an empty mock, it does not use the intended manual mock.

What have I done wrong?

2
can you share test file as well? also, just making sure, you are having relative path in jest.mock(), right? like import SoundPlayer from './sound-player'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructorSergey Semashko
No, I use absolute paths, both inside App.js and App.test.js. Is that what might be causing the problems? Using relative paths is difficult as I am working on a very large applicationJohan Book

2 Answers

0
votes

I see that your file structure is incorrect. The __mocks__ directory should immediately under components

src/
|- components/
|-- Foo.js 
|-- __mocks__
|--- Foo.jsx
|- App.js
|- App.test.js

Now Foo.js on main module directory can be something like this

function Foo() {
    return (
     
       <h1> Foo</h1>
    );
  }

  export default Foo;

And __mocks/Foo.js can be

console.log("Mock imported");

function Foo() {
    return (
     
       <h1> Mock</h1>
    );
  }

  export default Foo;

App.test.js will contain jest.mock call

import { render, screen } from '@testing-library/react';
import App from './App';


jest.mock("./components/Foo");

test('renders learn react link', () => {

 
  render(<App />);
  const linkElement = screen.getByText(/Mock/i); // Check that MOCK component is called
  expect(linkElement).toBeInTheDocument();
});

See the git repository for working sample https://github.com/meera/jest_mock

0
votes

Creating mock is a 3 step process:

  1. In App.js import Foo from 'components/Foo' imports Foo/index.js. Inside components create __mocks__/Foo/index.js and export mock component.
  2. Create a setup file for jest in project root jest.setup.js and declare jest.mock('src/components/Foo')
  3. In jest config, add option setupFilesAfterEnv: ['./jest.setup.js']