Jest:moduleNameMapper:模拟不适用于使用"moduleNameMapper"映射模块的导入模块



我在webpack中使用jest。Webpack 被配置为在某些导入中使用别名:

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

some-lib是添加到项目中的 git 子模块。 当我试图开玩笑地模拟导入的模块时,它不起作用

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

结果utilFunc没有被嘲笑。 伙计们,有人可以建议如何解决吗?

UPD:来自package.json的开玩笑配置的一部分

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

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

创建别名以更轻松地导入或需要某些模块。例如,为一堆常用的 src/文件夹添加别名。

换句话说,alias仅适用于导入或 require,而不适用于开玩笑函数。 webpack 所做的实际上是在编译时更改路径,因此当您的应用程序编译时,文件实际更改为什么。

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

如您所见,jest 保持不变,因此路径可能不存在,因此 jest 无法模拟它。 我建议使用 webpack 定义插件来创建一个名为 ABSOLUTE_SHARED_PATH 之类的全局变量。 将其添加到您的 .eslint 全局变量中,然后将其用于开玩笑,以便路径匹配。

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

JSON.stringify是使其成为字符串所必需的。 Webpack 使用定义插件进行了完美的 1 对 1 替换。这会将您的项目封装为双引号字符串。 尝试在控制台中对字符串进行 JSON.stringify 处理以获取更多信息。 如果你不这样做,这个 webpack 会抛出一个错误。

现在,当您更改代码中的笑话时

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

它将转换为正确的路径