This is my project folder structure,
Folder Structure
app
- api
- api1
__mocks__
index.js
- index.js
- api2
__mocks__
index.js
- index.js
- components
-component1
- index.js
__tests__
component1.test.js
Right now I have component1
which internally uses api1
to do some requests.
There are two issues that I am facing with the current folder structure and mocking the api modules.
api/__mocks__
? should it be index.js
(the same of as index.js
under api1
) or should it be api1.mocks.js
? Is there a naming convention that is required for jest?Jest Error:
jest-haste-map: duplicate manual mock found: Module name: index
Is there a documentation somewhere that talks about naming mocks?
This is my jest configuration from package.json,
package.json:
"jest": {
"testEnvironment": "jsdom",
"testPathDirs": [
"<app-path>"
],
"modulePaths": [
"<app-path>"
],
"enableAutomock": true,
"moduleNameMapper": {
"^components": "<rootDir>/components",
"^services": "<rootDir>/services",
"^api": "<rootDir>/api",
"^.+\\.less$": "<rootDir>/__mocks__/styleMocks.js"
}
}
Simple unit test:
import React from 'react';
import {mount} from 'enzyme';
import Component from 'components/Component1';
jest.mock('api/api1');
describe('Component1 Unit tests', () => {
it('Should render', () => {
const c1 = mount(
<Component1 />
);
expect(...);
});
});
Mocking Node modules If the module you are mocking is a Node module (e.g.: lodash ), the mock should be placed in the __mocks__ directory adjacent to node_modules (unless you configured roots to point to a folder other than the project root) and will be automatically mocked. There's no need to explicitly call jest.
With Jest's automatic mocks, we can mock classes or constructor functions easily. All methods are mocked with functions that return undefined . Then we can retrieve the mock by using mockedObject. mock.
To spy on an exported function in jest, you need to import all named exports and provide that object to the jest. spyOn function. That would look like this: import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest.
mock() doesn't work inside tests, only outside tests. Bookmark this question.
Yes, the documentation specifies that in Manual mocks section:
Manual mocks are defined by writing a module in a
__mocks__/
subdirectory immediately adjacent to the module. For example, to mock a module calleduser
in themodels
directory, create a file calleduser.js
and put it in themodels/__mocks__
directory.
That is the name of the mock should be the same as of the module.
When using moduleNameMapper
the docs read:
Modules that are mapped to an alias are unmocked by default.
I am not sure is Jest does not look for the mock either way.
Also please not that moduleNameMapper
does not work as you seem to assume it does. It does not replace the path parts, it resolves every require
starting with e.g. api
to <rootDir>/api
! (This the does not have any root file.). You should use ModulePaths instad.
The latest Jest v17 should give you more info about the duplicate.
Note: The config option enableAutomock
does not exist, did you mean automock
? (Or it should not be there at all?)
Note: Similar to naming convention for mocks, inside __tests__
folder test files usually keep the name of the module, too. The other approach is to add .spec
or .test
suffix and keep the test file in the same folder. In both cases it is the easy to find the corresponding test file. Therefore __tests__/index.js
or index.test.js
would be good names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With