Jasmine单元测试如何注入GooglePlaceModule解决地图库找不到报错
报错根因
抛Failed: Google maps library can not be found本质是两个问题:
- 你在
karma.conf.js里配的脚本URL粘串了,两个谷歌地图地址拼到一起根本加载不了;而且单测依赖外部公网脚本本身稳定性极差,跑本地或者CI环境随时可能因为网络问题挂,完全没必要用这种方案。 - 你手动给window挂google对象的时机不对:
GooglePlaceModule在compileComponents()执行初始化的时候就会检查全局google.maps对象是否存在,你等编译完才挂mock,人家早就校验完抛错了,而且你写的mock结构也不对,模块要校验的places相关属性根本没定义。
修复方案
不用引真实的谷歌SDK,直接在TestBed初始化之前挂结构正确的全局mock就行,改完的spec代码如下:
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { IonicModule } from '@ionic/angular'; import { ProfileFormComponent } from './profile-form.component'; import { ReactiveFormsModule } from '@angular/forms'; import { GooglePlaceModule } from 'ngx-google-places-autocomplete'; describe('ProfileFormComponent', () => { let component: ProfileFormComponent; let fixture: ComponentFixture<ProfileFormComponent>; beforeEach(waitForAsync(() => { // 必须在TestBed配置、组件编译前挂载mock,才能通过模块初始化阶段的存在性校验 (window as any).google = { maps: { places: { AutocompleteService: class {}, PlacesServiceStatus: { OK: 'OK', ZERO_RESULTS: 'ZERO_RESULTS', OVER_QUERY_LIMIT: 'OVER_QUERY_LIMIT', REQUEST_DENIED: 'REQUEST_DENIED', INVALID_REQUEST: 'INVALID_REQUEST', NOT_FOUND: 'NOT_FOUND', UNKNOWN_ERROR: 'UNKNOWN_ERROR' }, Autocomplete: class {} } } }; TestBed.configureTestingModule({ declarations: [ ProfileFormComponent ], imports: [IonicModule.forRoot(), ReactiveFormsModule, GooglePlaceModule] }).compileComponents(); fixture = TestBed.createComponent(ProfileFormComponent); component = fixture.componentInstance; fixture.detectChanges(); })); it('should create', () => { expect(component).toBeTruthy(); }); });
注意事项
- 之前在karma.conf.js里加的错误files配置直接删掉,不需要加载任何外部脚本,纯本地mock跑测试速度快,也不会受网络影响。
- 如果后续写其他用例用到了谷歌地图的更多API,直接在上面的mock对象里补对应方法的空实现即可,上面的mock足够支撑基础的组件创建用例正常通过。
内容的提问来源于stack exchange,提问作者D.Hodges
相关产品推荐
相关产品推荐

