alex.mironov
alex.mironov

Reputation: 2942

Jest:moduleNameMapper: mocks do not work for imported modules of mapped modules using "moduleNameMapper"

I use jest with webpack. Webpack is configured to use alias for some imports:

alias: {
  shared: path.resolve(process.cwd(), "some-lib/src"),
},
modules: ["app", "node_modules", "some-lib"],

some-lib is git submodule added to the project. When I'm trying to mock imported module in jest it doesn't work

jest.mock("shared/utils")
import { utilFunc } from "shared/utils"

as a result utilFunc is unmocked. Guys, can someone suggest please how to resolve it?

UPD: part of jest config from package.json

"moduleNameMapper": {
  "^api(.*)$": "<rootDir>/some-lib/src$1"
},

Upvotes: 2

Views: 5467

Answers (1)

thomasmeadows
thomasmeadows

Reputation: 1881

https://webpack.js.org/configuration/resolve/#resolve-alias

Create aliases to import or require certain modules more easily. For example, to alias a bunch of commonly used src/ folders.

In other words, alias only works with imports or requires, not jest functions. What webpack does is actually changes the path out at compile time so when your app compiles what the file actually gets changed to is.

jest.mock("shared/utils")
import { utilFunc } from "your_current_working_dir/some-lib/src/utils"

As you can see, jest is left unchanged, so the path probably does not exist, therefor jest cannot mock it. What I would recommend is using the webpack define plugin to create a global variable called something like ABSOLUTE_SHARED_PATH. Add it to your .eslint globals, then use that for jest so the paths match up.

new webpack.DefinePlugin({
  ABSOLUTE_SHARED_PATH: JSON.stringify(path.resolve(process.cwd(), "some-lib/src")
})

The JSON.stringify is necessary to make it a string. Webpack does a perfect 1 to 1 replacement with define plugin. This will encapsulate your item as a double quoted string. Try to JSON.stringify a string in the console for more info. If you don't do this webpack will throw an error.

Now, when you change jest in your code

jest.mock(path.resolve(ABSOLUTE_SHARED_PATH, "shared/utils"));

It will be transformed to the correct path

Upvotes: 1

Related Questions