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

Angular单元测试(Jasmine/Karma):google未定义及方法调用报错排查

解决Angular测试中"google is not defined"的报错

出现这个错误的核心原因是:测试环境未加载谷歌地图的JavaScript脚本,但你的GoogleCompleteDirective内部调用了google.maps.places.Autocomplete,导致全局google变量不存在。以下是三种可行的解决方法,按推荐程度排序:

方法1:用Mock类替代真实指令(推荐)

测试组件时,我们只需要验证组件是否正确调用了指令的方法,不需要测试指令的内部实现(那是指令专属spec的职责)。因此可以创建一个Mock指令替代真实的GoogleCompleteDirective,隔离外部依赖:

  1. 在component.spec.ts中定义Mock类:
class MockGoogleCompleteDirective {
  // 模拟指令的getComplete方法为spy
  getComplete = jasmine.createSpy('getComplete');
  // 如果组件还会调用getAutocomplete,也一并模拟
  getAutocomplete = jasmine.createSpy('getAutocomplete');
}
  1. 修改TestBed配置,替换真实指令为Mock类:
beforeEach(async () => {
  await TestBed.configureTestingModule({
    // ...你的组件声明、导入配置
    providers: [
      { provide: GoogleCompleteDirective, useClass: MockGoogleCompleteDirective },
      { provide: ElementRef, useValue: { nativeElement: document.createElement('input') } }
    ]
  }).compileComponents();
});
  1. 调整测试用例,验证组件与Mock指令的交互:
it('should call getComplete on GoogleCompleteDirective', () => {
  spyOn(component, 'ngAfterViewInit').and.callThrough();
  const mockDirective = TestBed.inject(GoogleCompleteDirective);
  
  component.ngAfterViewInit();
  
  expect(component.ngAfterViewInit).toHaveBeenCalled();
  // 验证getComplete是否被传入正确的参数调用
  expect(mockDirective.getComplete).toHaveBeenCalledWith(component.addresstext);
});

方法2:在测试环境中模拟全局google对象

如果需要测试真实指令的部分逻辑,可以在测试中手动模拟全局的google变量:

  1. 在component.spec.ts顶部声明全局window接口扩展:
declare global {
  interface Window {
    google: any;
  }
}
  1. 在beforeEach中初始化模拟的google对象:
beforeEach(() => {
  // 模拟谷歌地图的结构,将Autocomplete设为jasmine spy
  window.google = {
    maps: {
      places: {
        Autocomplete: jasmine.createSpy('Autocomplete')
      }
    }
  };
  
  // 初始化TestBed
  TestBed.configureTestingModule({
    // ...你的配置,使用真实的GoogleCompleteDirective
    providers: [GoogleCompleteDirective, { provide: ElementRef, useValue: { nativeElement: {} } }]
  });
});

这样当指令调用new google.maps.places.Autocomplete时,会触发这个spy,不会抛出"google is not defined"的错误。

方法3:在Karma中加载真实谷歌地图脚本(不推荐)

如果必须使用真实的谷歌地图逻辑,可以在Karma配置中添加外部脚本链接,但这种方法会让测试依赖网络,速度变慢且不稳定:

修改karma.conf.js的files数组,添加谷歌地图脚本:

module.exports = function(config) {
  config.set({
    // ...其他配置
    files: [
      'https://maps.googleapis.com/maps/api/js?key=你的API_KEY&libraries=places',
      // 你的测试文件路径
    ]
  });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:05:38