Angular执行ng test单元测试出现多类报错问题求助
HelloWorldComponent 单元测试报错问题
我为待测试的HelloWorldComponent搭建了单元测试环境,运行ng test时出现若干难以定位根因的错误,相关测试代码如下:
describe('HelloWorldComponent', () => { let component: HelloWorldComponent; let fixture: ComponentFixture<HelloWorldComponent>; let cookieValue: string; beforeEach(async(() => { const cookieSvcMock = jasmine.createSpyObj<CookieService>('CookieService', ['check', 'get', 'set', 'delete']); cookieValue = 'eyJ1c2VyX2lkIjoiNGJm.....'; mockedCookieService.check.and.returnValue(true); mockedCookieService.get.and.returnValue(cookieValue); const routes = [ {path: '/site1', component: AnotherComponent}, {path: '/site2', component: ComponentTwo} ] TestBed.configureTestingModule({ declarations: [HelloWorldComponent], imports: [ FormsModule, ReactiveFormsModule, MatInputModule, MatIconModule, MatSlideToggleModule, MatTooltipModule, RouterTestingModule.withRoutes((routes)), ], providers: [ {provide: ActivatedRoute, useValue: {params: of({id: 1})}}, {provide: CookieService, useValue: mockedCookieService}, ] }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(HelloWorldComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }); describe('get array of strings', () => { let helloWorldComponent = new HelloWorldComponent(null, new CookieService(document)); it('should return array', () => { const text = 'dsfsfsf@domain.comsfssdffdsf.Adfgdfg<>'; const textArr = ['dsfsfsf@domain.com'] let getTextArr: string[]; getTextArr = helloWorldComponent.getEmails(text); expect(getTextArr).toBe(textArr); }) })
运行报错信息
错误1:HelloWorldComponent > should create 路由组件未声明错误
失败:Component AnotherComponent不属于任何NgModule,或该组件所属模块未导入到当前测试模块中。
Error: Component AnotherComponent is not part of any NgModule or the module has not been imported into your module. at JitCompiler._createCompiledHostTemplate (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25915:1) at http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25891:1 at <Jasmine> at http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25888:1 at <Jasmine> at JitCompiler._compileComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25877:1) at http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25815:1 at Object.then (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2166:27) at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25813:1) at JitCompiler.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25775:1)
错误2:组件实例创建失败
组件创建断言失败,提示期望undefined为真值。
Error: Expected undefined to be truthy. at <Jasmine> at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/hello-world(hello-world.component.spec.ts:30:40) at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:359:1) at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:308:1)
错误3:get array of strings 用例令牌解析错误
InvalidTokenError: 指定的令牌无效:无法读取undefined对象的'replace'属性
at <Jasmine> at Object../node_modules/jwt-decode/lib/index.js (http://localhost:9876/_karma_webpack_/node_modules/jwt-decode/lib/index.js:9:1) at __webpack_require__ (http://localhost:9876/_karma_webpack_/webpack/bootstrap:79:1) at Module../hello-world.component.ts (http://localhost:9876/_karma_webpack_/main.js:1036:69) at __webpack_require__ (http://localhost:9876/_karma_webpack_/webpack/bootstrap:79:1) at Module../src/app/hello-world/hello-world.component.spec.ts (http://localhost:9876/_karma_webpack_/main.js:900:80) at __webpack_require__ (http://localhost:9876/_karma_webpack_/webpack/bootstrap:79:1) at Module../src/test.ts (http://localhost:9876/_karma_webpack_/src/test.ts:10:1) at __webpack_require__ (http://localhost:9876/_karma_webpack_/webpack/bootstrap:79:1) at checkDeferredModules (http://localhost:9876/_karma_webpack_/webpack/bootstrap:45:1) at http://localhost:9876/_karma_webpack_/webpack/bootstrap:152:1
修复方案
- 路由组件未声明问题:
RouterTestingModule加载路由配置时会校验所有配置的组件是否在当前测试模块中声明。如果测试不需要实际跳转加载AnotherComponent、ComponentTwo,直接创建空桩组件替换路由配置里的真实组件即可;如果需要测试路由相关逻辑,把两个组件加入测试模块的declarations数组,或者直接导入两个组件所属的业务模块。 - 组件实例为undefined问题:代码里定义Cookie服务mock的变量名是
cookieSvcMock,但后续设置返回值、传入providers数组时用的是未定义的mockedCookieService,导致实际注入的服务为undefined,组件初始化失败。统一变量名即可解决。 - JWT解析报错问题:第二个测试块直接手动new组件实例时,第一个构造参数传了null,第二个参数传了未做mock的真实
CookieService实例,组件初始化时调用jwt-decode解析Cookie拿到的是undefined值,触发replace属性读取错误。测试纯工具方法getEmails时,不需要实例化完整组件,要么把方法提取为纯工具函数独立测试,要么mock所有构造函数依赖的服务,不要传null或未初始化的真实服务。另外数组断言要用toEqual做值比较,toBe是引用比较,两个内容相同的不同数组实例会判定为不相等。
内容的提问来源于stack exchange,提问作者Hiraja
相关产品推荐
相关产品推荐

