You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 14升级至15后单元测试失败问题求助

Angular 14升级到15后单元测试报错解决方案

一、解决TypeScript HeritageClause错误

核心原因

你的Nx版本(14.8.9)与Angular 15不兼容,Nx主版本必须和Angular保持一致,Nx14无法正确解析Angular15对应的TypeScript语法结构。

解决方案

  1. 升级Nx到15.x版本:
    nx migrate latest --from=14.8.9
    
    按照终端提示依次执行npm install和nx migrate --run-migrations完成全量升级,确保@nrwl/jest、@nrwl/angular等所有Nx相关包都同步到15.x版本。
  2. 同步依赖版本:
    • 将rxjs升级到~7.5.0(Angular15官方推荐版本)
    • 将tslib升级到^2.4.0
    • 将zone.js升级到~0.12.0

二、解决ReferenceError: Window is not defined错误

该错误是因为Jest运行在Node.js环境,不存在浏览器原生的Window对象,需通过以下方式模拟注入的WINDOW令牌:

方案1:测试模块内局部模拟

在user-management.module.spec.ts中为测试模块提供模拟的Window对象:

import { TestBed } from '@angular/core/testing';
import { UserManagementModule } from './user-management.module';
import { WINDOW } from '../../common-ui/src/lib/window/window-manager.service';

describe('UserManagementModule', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [UserManagementModule],
      providers: [
        {
          provide: WINDOW,
          useValue: {
            location: { href: '' },
            navigator: { userAgent: '' }
            // 添加代码中依赖的其他Window属性
          } as unknown as Window
        }
      ]
    }).compileComponents();
  });

  // 测试用例编写...
});

方案2:全局Jest配置模拟

  1. 在jest配置文件(如jest.config.ts)中添加全局初始化文件:
    export default {
      // 其他已有配置
      setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts']
    };
    
  2. 在src/test-setup.ts中全局模拟Window:
    global.window = {
      location: { href: '' },
      navigator: { userAgent: '' }
      // 补充所需属性
    } as unknown as Window;
    global.Window = global.window;
    

方案3:修改Window服务注入逻辑

在window-manager.service.ts中加入平台判断,非浏览器环境自动返回模拟对象:

import { Injectable, Inject, PLATFORM_ID, InjectionToken } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

export const WINDOW = new InjectionToken<Window>('WindowToken');

@Injectable()
export class WindowManagerService {
  private readonly windowInstance: Window;

  constructor(
    @Inject(PLATFORM_ID) private platformId: object,
    @Inject(WINDOW) window?: Window
  ) {
    this.windowInstance = isPlatformBrowser(this.platformId) 
      ? window! 
      : ({ location: {}, navigator: {} } as unknown as Window);
  }

  // 服务原有方法...
}

// 在对应模块的providers中调整WINDOW令牌的提供逻辑
{
  provide: WINDOW,
  useFactory: (platformId: object) => {
    return isPlatformBrowser(platformId) ? window : ({ location: {}, navigator: {} } as unknown as Window);
  },
  deps: [PLATFORM_ID]
}

完成以上调整后,执行npm install更新依赖,重新运行单元测试即可解决问题。

内容的提问来源于stack exchange,提问作者mack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:50:57