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

Angular中Jest单元测试如何模拟__webpack_public_path__变量

问题:Angular测试中模拟__webpack_public_path__失败

场景重现

组件代码:

import { Component } from '@angular/core';

import { getImageUrl } from '../../shared/get-image-url';

@Component({
  selector: 'ice-section-banner-invite-client',
  templateUrl: './section-banner-invite-client.component.html',
  styleUrls: ['./section-banner-invite-client.component.scss'],
})
export class IceSectionBannerInviteClient {
  public loading = false;

  public imageUrl = `url(${getImageUrl('assets/images/banner-criar-conta.png')})`;

  constructor() {
    console.log(this.imageUrl);
  }

  public clickInviteClient(): void {
    window.open(`${document.location.origin}${'/br-iceberg/invitations'}`);
  }
}

工具函数代码:

export function getImageUrl(imageName: string) {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-expect-error
  // eslint-disable-next-line camelcase
  let publicPath: string = __webpack_public_path__;
  publicPath = publicPath.endsWith('/') ? publicPath.slice(0, -1) : publicPath;

  return `${publicPath}/${imageName}`;
}

测试文件代码:

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { OnDashboardModule } from '@onviobr/dashboard';
import { TranslateTestingModule } from 'ngx-translate-testing';

import { IceSectionBannerInviteClient } from './section-banner-invite-client.component';

describe('IceSectionBannerInviteClient', () => {
  let component: IceSectionBannerInviteClient;
  let fixture: ComponentFixture<IceSectionBannerInviteClient>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [IceSectionBannerInviteClient],
      imports: [
        OnDashboardModule,
        TranslateTestingModule.withTranslations({}),
        RouterTestingModule.withRoutes([]),
        HttpClientTestingModule,
      ],
      schemas: [NO_ERRORS_SCHEMA],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(IceSectionBannerInviteClient);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

运行测试时报错:

IceSectionBannerInviteClient › should create

    ReferenceError: __webpack_public_path__ is not defined

已尝试的无效操作:

  • 在spec文件中配置providers: [{ provide: __webpack__public__path__, useValue: 'teste' }],
  • 在spec文件中执行process.env = Object.assign(process.env, { __webpack__public__path__: 'teste' });
  • 在spec文件中执行process.env.__webpack__public__path__ = 'teste';
  • 在jest.config.js中执行process.env = Object.assign(process.env, { __webpack__public__path__: 'teste' });
  • 在jest.config.js中设置globals: {__webpack__public__path__: 'value',}
  • 在jest.config.js中配置jest: { setupFiles: ['<rootDir>/setup.js'] },并在setup.js中添加process.env.__webpack__public__path__ = 'value';

另外使用process.env时提示Cannot find name 'process'.,但tsconfig已配置"compilerOptions": { "types": ["node"] }。


解决方案

方案1:在测试文件中直接声明并赋值全局变量

在测试文件的所有import之后、describe之前添加以下代码:

// 声明全局变量,解决TS类型报错
declare global {
  var __webpack_public_path__: string;
}

// 给变量赋值模拟路径
__webpack_public_path__ = '/test-public-path/';

测试运行时,getImageUrl函数就能获取到这个全局变量的值,不会抛出未定义错误。

方案2:Mock工具函数绕过依赖

如果测试只需要验证组件能否正常创建,不需要测试getImageUrl的逻辑,可以直接mock这个函数:

import { getImageUrl } from '../../shared/get-image-url';

// 在describe之前mock工具函数
jest.mock('../../shared/get-image-url', () => ({
  getImageUrl: jest.fn(() => '/test-path/assets/images/banner-criar-conta.png')
}));

describe('IceSectionBannerInviteClient', () => {
  // 原有测试代码保持不变
});

这种方式直接跳过__webpack_public_path__的依赖,专注于组件本身的测试逻辑。

方案3:修复process.env的TS类型问题(若坚持用环境变量方案)

  1. 确保tsconfig.spec.json中也添加了node和jest类型:
{
  "compilerOptions": {
    "types": ["node", "jest"]
  }
}
  1. 创建setup-jest.ts文件并添加:
(global as any).__webpack_public_path__ = process.env.WEBPACK_PUBLIC_PATH || '/default-path/';
  1. 在jest.config.js中配置:
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
  // 其他现有配置...
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:15:29