单元测试因找不到模块而失败,但VS Code能找到该路径
我正在把Angular从 20升级到21。
我的所有单元测试都失败了,混合出现了“Cannot find module” @angular/core/testing, @angular/common/http/testing 或 @angular/common/http/testing。
src/app/service/user-group-service.spec.ts:1:25 - error TS2307: Cannot find module '@angular/core/testing' or its corresponding type declarations.
1 import { TestBed } from '@angular/core/testing';
~~~~~~~~~~~~~~~~~~~~~~~
src/app/service/user-group-service.spec.ts:3:65 - error TS2307: Cannot find module '@angular/common/http/testing' or its corresponding type declarations.
3 import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/app/service/user-group-service.spec.ts:4:35 - error TS2307: Cannot find module '@angular/common/http' or its corresponding type declarations.
4 import { provideHttpClient } from '@angular/common/http';
~~~~~~~~~~~~~~~~~~~~~~
我在VS Code里可以输入 import TestBed,并得到自动完成提示,所以我知道这些文件确实存在。
但在执行 npm run test 时(它被简单映射到 jest 命令)单元测试失败。
这就说明Jest或 TypeScript出现了问题。
我对配置文件做的任何修改似乎都无法解决这个问题。
$ ng version
Angular CLI : 21.2.12
Angular : 21.2.14
Node.js : 22.22.2
Package Manager : npm 11.12.0
Operating System : darwin arm64
┌───────────────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular-devkit/build-angular │ 21.2.12 │ ~21.2.12 │
│ @angular/animations │ 21.2.14 │ ~21.2.14 │
│ @angular/cdk │ 20.2.14 │ ^20.2.14 │
│ @angular/cli │ 21.2.12 │ ~21.2.12 │
│ @angular/common │ 21.2.14 │ ~21.2.14 │
│ @angular/compiler │ 21.2.14 │ ~21.2.14 │
│ @angular/compiler-cli │ 21.2.14 │ ~21.2.14 │
│ @angular/core │ 21.2.14 │ ~21.2.14 │
│ @angular/forms │ 21.2.14 │ ~21.2.14 │
│ @angular/language-service │ 21.2.14 │ ~21.2.14 │
│ @angular/platform-browser │ 21.2.14 │ ~21.2.14 │
│ @angular/platform-browser-dynamic │ 21.2.14 │ ~21.2.14 │
│ @angular/router │ 21.2.14 │ ~21.2.14 │
│ rxjs │ 7.8.2 │ ~7.8.2 │
│ typescript │ 5.9.3 │ ^5.9.3 │
│ zone.js │ 0.15.1 │ ~0.15.1 │
└───────────────────────────────────┴───────────────────┴───────────────────┘
// tsconfig.json
{
"compileOnSave": false,
"isolatedModules": true,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"esModuleInterop": true,
"sourceMap": true,
"declaration": false,
"module": "es2015",
"moduleResolution": "bundler",
"experimentalDecorators": true,
"importHelpers": false,
"target": "es2022",
"typeRoots": [
"node_modules/@types"
],
"useDefineForClassFields": false
}
}
// jest.config.ts
import type { Config } from 'jest';
const config: Config = {
verbose: true,
preset: 'jest-preset-angular',
injectGlobals: true,
testEnvironment: 'jest-environment-jsdom',
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
useESM: true,
},
],
},
reporters: ['jest-simple-dot-reporter'],
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
modulePathIgnorePatterns: [
// These ignores are needed when run inside the container
"<rootDir>/.SAVED",
"<rootDir>/.container_node_modules_amd64"
],
moduleNameMapper: {
'^src/(.*)$': '<rootDir>/src/$1',
'^app/(.*)$': '<rootDir>/src/app/$1',
'^assets/(.*)$': '<rootDir>/src/assets/$1',
'^environments/(.*)$': '<rootDir>/src/environments/$1',
},
collectCoverage: true,
collectCoverageFrom: [
// '**/*.{ts,js,jsx}',
'src/**/*.{ts,js,jsx}', '!src/environments/**'
],
coverageProvider: 'v8',
coverageReporters: [
'html',
'text-summary',
],
coveragePathIgnorePatterns: [
'src/app/model',
'src/app/mailing-lists/model',
'src/main.ts',
'src/polyfills.ts',
'src/zone-flags.ts',
'src/app/app.module.ts',
]
};
export default config;
// tsconfig.spec.json
{
"compileOnSave": false,
"extends": "./tsconfig.json",
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"],
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"esModuleInterop": true,
"sourceMap": true,
"declaration": false,
"module": "es2015",
"moduleResolution": "node",
"experimentalDecorators": true,
"importHelpers": true,
"target": "ESNext",
"types": ["jest", "node"],
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
],
"useDefineForClassFields": false
}
}
解决方案
可以尝试这里的解决方案,针对失败的测试有类似的问题: https://github.com/nrwl/nx/issues/33777#issuecomment-3674675041
我们通过在tsconfig.spec.json中添加以下内容使其工作:
"allowSyntheticDefaultImports": true, "resolveJsonModule": true, "isolatedModules": true
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。