网站搜索

typescript - Jest 配置/错误 - 无法从“”中找到模块“”


启动测试时出现 Jest 错误

我正在为 Obsidian 构建一个插件,并且我从他们在 GitHub 上的插件模板搭建了我的项目。

为了开发一个强大的插件,我想用 Jest 设置单元测试。然后,我为我的插件写了一个简单的单元测试,并在测试文件中导入了 obsidian 模块。然而,当运行测试时,它产生了以下错误:

 FAIL  tests/sync_algorithm.test.ts
  ● Test suite failed to run

    Cannot find module 'obsidian' from 'tests/sync_algorithm.test.ts'

      1 | import { syncAlgorithm } from "../src/sync_algorithm";
    > 2 | import { TFile } from "obsidian";
        | ^
      3 |
      4 | describe("Sync algorithm", () => {
      5 |       beforeEach(() => {});

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
      at Object.<anonymous> (tests/sync_algorithm.test.ts:2:1)

我的配置

  • TypeScript : 4.7.4
  • Jest : ^29.4.2
  • ts-jest : ^29.0.5
  • 黑曜石 : ^1.1.1

集成开发环境:VS 代码

package.json

以下是来自 package.json 文件的重要信息:

{
  ...
  "scripts": {
    ...
    "test": "jest"
  },
  ...
  "devDependencies": {
    "@codemirror/state": "^6.2.0",
    "@codemirror/view": "^6.8.1",
    "@types/jest": "^29.4.0",
    "@types/node": "^16.18.12",
    "@typescript-eslint/eslint-plugin": "5.29.0",
    "@typescript-eslint/parser": "5.29.0",
    "builtin-modules": "3.3.0",
    "esbuild": "0.17.3",
    "eslint": "^8.34.0",
    "jest": "^29.4.2",
    "obsidian": "^1.1.1",
    "ts-jest": "^29.0.5",
    "ts-node": "^10.9.1",
    "tslib": "2.4.0",
    "typescript": "4.7.4"
  }
}

jest.config.ts

export default {
    moduleDirectories: ["node_modules", "node_modules/.pnpm", "src"],
    modulePaths: ["<rootDir>"],
    moduleFileExtensions: [
        "js",
        "mjs",
        "cjs",
        "jsx",
        "ts",
        "tsx",
        "json",
        "node",
    ],
    moduleNameMapper: {
        // obsidian:
        //  "<rootDir>//node_modules/.pnpm/[email _cknrwgf45skglbt6g7kref4zeq/node_modules/obsidian",
        "./node_modules/(.*)": "<rootDir>/node_modules/$1",
    },
    transform: {
        "^.+\\.ts$": "ts-jest",
    },
};

tsconfig.json

{
    "compilerOptions": {
        "baseUrl": ".",
        "inlineSourceMap": true,
        "inlineSources": true,
        "module": "ESNext",
        "target": "ES6",
        "allowJs": true,
        "noImplicitAny": true,
        "moduleResolution": "node",
        "importHelpers": true,
        "isolatedModules": true,
        "strictNullChecks": true,
        "esModuleInterop": true,
        "lib": [
            "DOM",
            "ES5",
            "ES6",
            "ES7"
        ]
    },
    "include": [
        "**/*.ts"
    ],
}

我尝试过的

更改包管理器

我最初使用 pnpm 安装了该项目。然而,由于这个包管理器使用符号链接来管理包,我认为这可能是问题的原因。

所以我使用 npm 更改并重新安装了所有依赖项。然而,错误仍然出现。

我也尝试了 yarn,但错误仍然存在。

更改配置文件(上面的那些)

我尝试了很多在我使用的包、jest.config.ts 或 jest.config.js 和 tsconfig.json 文件中的更改。

其他尝试

我根据搜索尝试更改了包管理器和配置。

这里有一些已经为 Obsidian 构建的插件,它们使用 Jest 进行测试。我尝试重现它们的配置:

  • 黑曜石模板器
  • 黑曜石日历插件
  • 黑曜石插件 - 动态目录

后者是我找到一个包含 Obsidian 模块导入的 Jest 配置文件和测试文件的项目。我将其克隆到本地并成功运行了所有测试。

但是在我的代码库中重现配置时没有成功。

我在这个问题上的搜索

这是我阅读的一些资源,用于相应地更改配置并解决此错误:

  • Jest 在使用绝对路径导入组件时会给出 `Cannot find module`
  • 无法从 setup-jest.js 中找到模块
  • TS 无法找到模块
  • 我如何解决 Jest Mock 错误 “找不到模块”
  • Jest:无法找到在待测试模块中所需的模块(相对路径)
  • 运行 jest 时 Typescript 路径无法解析?
  • Jest、ts-jest、TypeScript 使用 ES 模块导入:找不到模块
  • Jest + TypeScript + 绝对路径 (baseUrl) 报错:找不到模块

设置 Jest 和 TypeScript 的有用资源

  • ts-jest 安装
  • Jest 配置
  • ts-jest 故障排除
  • TypeScript 文档 - 模块解析

提前感谢任何帮助或建议,使其能够正常工作。

答案#1

我在我的项目中遇到了类似的情况。我发现被引用模块的 package.json 中缺少 "main"

{
  ..
  "main": "lib/index.js",
  "module": "lib/index.js",
  "types": "lib/index.d.ts",
  "scripts": {
    ..
  }
}

答案#2

你为什么没有模拟这个模块?比如说:

jest.mock('./moduleName') //replace with obsidian

或你想测试的部分(函数/构造等):

jest.mock('./moduleName', () => ({
  <function>: () => jest.fn(),
}));

参见 Jest.io 手册模拟

obsidian/TFile 示例:

// Create a mock for the TFile class
jest.mock('obsidian', () => {
  return {
    TFile: jest.fn().mockImplementation(() => {
      return {
        // Add any methods or properties you want to mock
        basename: 'mock-basename.md',
        path: 'mock-path',
        extension: 'md',
        stat: jest.fn(),
      };
    }),
  };
});

我建议采用这种方法,因为你不需要测试库。你应该旨在在与外部依赖隔离的情况下测试代码的功能。这是因为像库这样的外部依赖可能是不可预测的,它们的行为可能会在你不知情的情况下发生变化,从而使你的测试不可靠。

相关文章