为什么 [object ErrorEvent] 只有在测试都是 运行 时才会抛出?
Why is [object ErrorEvent] thrown only when the tests are all running?
我仍在努力弄清楚 angular 测试,我正在为失败的测试而苦苦挣扎。当我 运行 使用 ng-test
进行测试时,Chrome 输出显示此错误:
CustomerComponent should create
[object ErrorEvent] thrown
控制台内容如下:
zone.js:192 Uncaught TypeError: _this.handler.handle is not a function
at MergeMapSubscriber.project (:9876/_karma_webpack_/webpack:/node_modules/@angular/common/fesm5/http.js:974)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:60)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:50)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:54)
at Observable._subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/observable/scalar.js:5)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:42)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:28)
at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:28)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:23)
at FilterOperator.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/filter.js:15)
at ____________________Elapsed_12_ms__At__Mon_Oct_22_2018_15_18_53_GMT_0200__heure_d__t__d_Europe_centrale_ ()
at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:108)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:297)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:232)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:255)
at scheduleMacroTaskWithCurrentZone (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1114)
at :9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:2090
测试文件是...好吧,我想是你能找到的最基本的。
class MockCustomerService {
public addUserInformations(): Observable<Customer> {
return of(new Customer());
}
public updateCustomerInformations(): Observable<Customer> {
return of(new Customer());
}
}
export class PartialTranslateServiceStub {
addLangs(langs: Array<string>): void { }
instant (key: string): any { }
}
describe('CustomerComponent', () => {
let component: CustomerComponent;
let fixture: ComponentFixture<CustomerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CustomerComponent, ModalComponent, SecondComponent],
providers: [FormBuilder, ConfigurationService,
{ provide: TranslateService, useClass: PartialTranslateServiceStub },
{ provide: CustomerService, useClass: MockCustomerService }
],
imports: [FormsModule, ReactiveFormsModule, RouterTestingModule, TranslateModule.forRoot()]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CustomerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
我看到大多数答案都是为订阅者添加错误处理程序,但那已经完成了。
此外,我尝试从头开始重新制作组件并且...当我创建一个新组件时,失败的测试成功了。删除组件使测试再次失败。
更新
备注:如果我对失败的测试进行评论,那么问题将移至下一个测试。奇怪。
您的问题似乎来自 mergeMap。我的猜测是 TranslateLoader 是罪魁祸首。
你为什么在测试中使用真实的东西?我建议像这样创建一个 TranslateModule 存根:
export class PartialTranslateServiceStub {
addLangs(langs: Array<string>): void { }
instant (key: string): any { }
}
并在测试中删除翻译模块并使用存根作为提供者:
providers: [FormBuilder, CustomerService, ConfigurationService,
{provide: TranslateService, useClass: TranslateServiceStub},
ApiRequestService, AppConfig, HttpClient, HttpHandler],
imports: [FormsModule, ReactiveFormsModule, RouterTestingModule]
回答
问题已解决。
失败之前的测试运行没有正确完成,从而影响了后续。似乎问题来自未正确模拟的提供者:例如,而不是 MockPreviousService
,它更像是 PreviousService
、DependencyOne
、DependencyTwo
。它在测试用例中没有用,所以去掉声明并模拟服务就可以了。
我仍在努力弄清楚 angular 测试,我正在为失败的测试而苦苦挣扎。当我 运行 使用 ng-test
进行测试时,Chrome 输出显示此错误:
CustomerComponent should create
[object ErrorEvent] thrown
控制台内容如下:
zone.js:192 Uncaught TypeError: _this.handler.handle is not a function
at MergeMapSubscriber.project (:9876/_karma_webpack_/webpack:/node_modules/@angular/common/fesm5/http.js:974)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:60)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:50)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:54)
at Observable._subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/observable/scalar.js:5)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:42)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:28)
at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:28)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:23)
at FilterOperator.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/filter.js:15)
at ____________________Elapsed_12_ms__At__Mon_Oct_22_2018_15_18_53_GMT_0200__heure_d__t__d_Europe_centrale_ ()
at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:108)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:297)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:232)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:255)
at scheduleMacroTaskWithCurrentZone (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1114)
at :9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:2090
测试文件是...好吧,我想是你能找到的最基本的。
class MockCustomerService {
public addUserInformations(): Observable<Customer> {
return of(new Customer());
}
public updateCustomerInformations(): Observable<Customer> {
return of(new Customer());
}
}
export class PartialTranslateServiceStub {
addLangs(langs: Array<string>): void { }
instant (key: string): any { }
}
describe('CustomerComponent', () => {
let component: CustomerComponent;
let fixture: ComponentFixture<CustomerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CustomerComponent, ModalComponent, SecondComponent],
providers: [FormBuilder, ConfigurationService,
{ provide: TranslateService, useClass: PartialTranslateServiceStub },
{ provide: CustomerService, useClass: MockCustomerService }
],
imports: [FormsModule, ReactiveFormsModule, RouterTestingModule, TranslateModule.forRoot()]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CustomerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
我看到大多数答案都是为订阅者添加错误处理程序,但那已经完成了。
此外,我尝试从头开始重新制作组件并且...当我创建一个新组件时,失败的测试成功了。删除组件使测试再次失败。
更新
备注:如果我对失败的测试进行评论,那么问题将移至下一个测试。奇怪。
您的问题似乎来自 mergeMap。我的猜测是 TranslateLoader 是罪魁祸首。
你为什么在测试中使用真实的东西?我建议像这样创建一个 TranslateModule 存根:
export class PartialTranslateServiceStub {
addLangs(langs: Array<string>): void { }
instant (key: string): any { }
}
并在测试中删除翻译模块并使用存根作为提供者:
providers: [FormBuilder, CustomerService, ConfigurationService,
{provide: TranslateService, useClass: TranslateServiceStub},
ApiRequestService, AppConfig, HttpClient, HttpHandler],
imports: [FormsModule, ReactiveFormsModule, RouterTestingModule]
回答
问题已解决。
失败之前的测试运行没有正确完成,从而影响了后续。似乎问题来自未正确模拟的提供者:例如,而不是 MockPreviousService
,它更像是 PreviousService
、DependencyOne
、DependencyTwo
。它在测试用例中没有用,所以去掉声明并模拟服务就可以了。