使用 import.meta 导致测试失败(Jest + React + Typescript + Vite)

问题描述 投票:0回答:2

在最初使用 Create-react-app 设置然后迁移到 jest 的应用程序上,由于 import.meta ,测试开始失败 由于某种原因, import.meta 的情况,我通过使用 ts-jest-mock-import-meta 库在 .tsx 文件上得到了解决,但在 .ts 上它们一直失败。

我按照以下方式设置了 jest.config.ts:

export default {
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',
  transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        diagnostics: {
          ignoreCodes: [1343],
        },
        astTransformers: {
          before: [
            {
              path: 'node_modules/ts-jest-mock-import-meta', // or, alternatively, 'ts-jest-mock-import-meta' directly, without node_modules.
              options: {
                metaObjectReplacement: {
                  API_ENDPOINT: 'https://www.url.com',
                  test2: 'test2',
                  test3: 'test3',
                },
              },
            },
          ],
        },
      },
    ],
  },
  moduleNameMapper: {
    '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/src/test/__mocks__/fileMock.js',
    '\\.(css|less)$': '<rootDir>/src/test/__mocks__/styleMock.js',
  },
  setupFiles: ['<rootDir>/jest.setup.ts'],
  type: 'module',
};

我正在使用 ts-jest-mock-import-meta 库。即使问题在 tsx 文件上得到解决,我在 ts 文件上有一些 import.meta 导致测试失败,因为说 import.meta.env.API_ENDPOINT 未定义。

{
  "name": "test-env-event",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "test": "jest"
  },
  "dependencies": {
    "fetch-event-source": "^1.0.0-alpha.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^6.4.1",
    "@testing-library/react": "^14.2.1",
    "@types/jest": "^29.5.12",
    "@types/react": "^18.2.43",
    "@types/react-dom": "^18.2.17",
    "@typescript-eslint/eslint-plugin": "^6.14.0",
    "@typescript-eslint/parser": "^6.14.0",
    "@vitejs/plugin-react": "^4.2.1",
    "cross-fetch": "^4.0.0",
    "eslint": "^8.55.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.5",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "ts-jest": "^29.1.2",
    "ts-jest-mock-import-meta": "^1.2.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.2.2",
    "vite": "^5.0.8"
  }
}

我的 package.json 包含以下库。任何帮助将不胜感激。

另一个注意事项是我需要有条件地调用我的环境变量,因此它们在某些情况下可能是未定义的:

const apiURL = import.meta.env.API_URL ? `${import.meta.env.API_URL}` : "http://localhost:8080"

谢谢

reactjs typescript jestjs vite ts-jest
2个回答
0
投票

使用 vite-plugin-environment 并使用 process.env 重新打包 import.meta 解决了问题


0
投票

我遇到了类似的挑战,并根据情况探索了多种方法。在尝试了各种方法后,我发现了最简单且最无错误的解决方案。

我亲自导入所有环境变量并将它们分配给一个常量以在整个项目中使用。 关键思想是模拟此文件。通过使用模拟环境值,jest 不会实际执行该文件,这可以防止与 import.meta 相关的错误。

以下是如何实施的示例:

//config.ts

    const required = (key: string, defaultValue = undefined) => {
      const value = import.meta.env[key] || process.env[key] || defaultValue;
      if (value == null) {
        throw new Error(`Key ${key} is undefined`);
      }
      return value;
    };
    
    export const config = {
      server: {
        url: `${required('VITE_SERVER_URL')}}`,
      },
    };



//App.test.ts
jest.mock('./config', () => ({
  config: {
    server: {
      url: 'http://localhost:8080',
    },
  },
}));

我还尝试了另一种使用 ts-jest/presets/default-esm 的方法,如下所示:

module.exports = {
  preset: 'ts-jest/presets/default-esm',
}

此方法可以在此 GitHub 问题中查看(https://github.com/kulshekhar/ts-jest/issues/3888#issuecomment-1336490015

虽然这给我带来了额外的麻烦,但许多其他人已经使用它成功解决了他们的问题,所以我包含了链接以供参考。

希望这种方法之一可以解决您的问题:)

© www.soinside.com 2019 - 2024. All rights reserved.