【发布时间】:2021-12-21 00:52:30
【问题描述】:
我正在使用 Karma 和 jasmine 对我的组件进行单元测试。 fixture.detechChanges() 应该用于每个测试以检测更改。但是这种方法会使测试用例失败并给出错误
错误:InvalidPipeArgument: 'Unable to convert "Invalid Date" into a date' for pipe 'DatePipe'
由于我是新手,任何人都可以让我知道为什么会这样,以及使用它的正确位置是什么。
在三个测试用例中,第二个测试用例失败了。我做了很多研究,但我不确定为什么我的测试用例失败了。
下面是我的代码
组件.ts
export class ResourceOverviewComponent implements OnInit {
id = '--';
lastupdated : any;
creationDate = '--'
description = '--'
tags = '--'
dateTimeFormat = 'MMM d, y h:mm a';
dateTimeZone: any;
constructor(
private readonly resourceOverviewService: ResourceOverviewService,
private readonly utilsService: UtilsService,
private readonly router: Router,
readonly route: ActivatedRoute,
) {}
ngOnInit() {
this.id = this.route.snapshot.queryParamMap.get('id');
this.getDetails();
}
viewInventory(){
this.router.navigate(['..'], {
relativeTo: this.route
});
}
getDetails() {
if (this.id) {
this.getResourceOverview();
}
}
getResourceOverview(): void {
const resourceID = `search_keys=${"resource_id"}&search=${this.id}`
this.resourceId = this.id
this.resourceOverviewService
.getResourceOverview(resourceID)
.subscribe(
(response) => {
const result = response as any;
if (result && result.raw_items[0]) {
this.creationDate = result.raw_resource_created || '--' ;
}
},
(error) => {
console.log('Resource overview details failed with error', error);
}
);
}
}
component.spec.ts
class mockHttpWrapperService {
readonly isApiReady = false;
}
describe('SomeComponent', () => {
let component: SomeComponent;
let fixture: ComponentFixture<SomeComponent>;
let someService: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SomeComponent ],
imports: [
some module,some-module,somemodule.forRoot(),
RouterModule.forRoot([]),
],
providers: [
{ provide: NGXLogger, useClass: MockNGXLogger },
{ provide: HttpWrapperService, useClass: mockHttpWrapperService },
{ provide: Router, useClass: class { navigate = jasmine.createSpy("navigate"); }},
ApiService,
SomeService,
SomeService,
SomeService,
SomeService,
{
provide: ActivatedRoute,
useValue: {
params: of({ id: 'aeb24ca0549c', code: 'IBM' }),
snapshot: {
queryParamMap: convertToParamMap({
id: 'aeb24ca0549c',
code: 'IBM',
})
}
}
},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
.compileComponents()
}));
beforeEach(() => {
fixture = TestBed.createComponent(SomeComponent);
component = fixture.debugElement.componentInstance;
// fixture.detectChanges();
});
it('should create component ', () => {
expect(component).toBeTruthy();
});
it('should init object for action tabs', async () => {
await fixture.whenStable();
component.ngOnInit();
fixture.detectChanges();
expect(component).toBeTruthy();
});
it('should get resource data ', () => {
someService = TestBed.inject(SomeService);
const data = {some-xyz-object};
spyOn(someService, "getResourceOverview").and.callFake(() => {
return of(data)
})
component.getDetails();
fixture.detectChanges();
expect(component).toBeTruthy();
});
});
component.html
<div class="container-wrapper">
<div class="breadcrumWrapper" >
<ibm-breadcrumb>
<ibm-breadcrumb-item >
{{ id }}
</ibm-breadcrumb-item>
</ibm-breadcrumb>
<div class="breadcrumWrapper" >
</div>
<div>
</div>
</div>
<div class="container-overview" >
<div class="overview" >
</div>
<div class="marginTop ">
<div class="bx--row">
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ id }}"
>{{ id }}</span
>
</div>
</div>
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ resourceType }}"
>{{ resourceType }}</span
>
</div>
</div>
</div>
<div class="bx--row">
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ region }}"
>{{ region }}</span
>
</div>
</div>
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<div *ngFor="let k of keyValue; let i = index;">
<span *ngIf="i!=(keyValue.length-1)"
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ id }}"
>{{ k.Key }} : {{ k.Value }} ,
</span>
<span *ngIf="i==(keyValue.length-1)"
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ id }}"
>{{ k.Key }}:{{ k.Value }}
</span>
</div>
</div>
</div>
</div>
<div class="bx--row">
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ correlationID }}"
>{{ correlationID }}</span
>
</div>
</div>
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ resourceCategory }}"
>{{ resourceCategory }}</span
>
</div>
</div>
</div>
<div *ngIf="showMore">
<div class="bx--row">
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ status }}"
>{{ status }}</span
>
</div>
</div>
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ provider }}"
>{{ provider }}</span
>
</div>
</div>
</div>
<div class="bx--row">
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ providerAccount }}"
>{{ providerAccount }}</span
>
</div>
</div>
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ resourceName }}"
>{{ resourceName }}</span
>
</div>
</div>
</div>
</div>
</div>
<div class="container-overview complex-data-viewer-wrap" >
<div class="bx--row">
<div class="bx--col-xs-6">
<div class="bx--row rowMargins">
<span
class="ellipsis overViewcontent bx--col-xs-5"
title="{{ creationDate }}"
>{{ creationDate }}</span
>
</div>
</div>
</div>
</div>
【问题讨论】:
-
我认为问题不在于fixture.detectChanges(),在测试用例执行期间,DatePipe 期望有效日期,并且由于您没有模拟任何组件实例属性,因此您看到了该错误,请尝试模拟局部变量或使用条件运算符检查 main 方法中的 null/undefined。
-
但是这里的第三个测试用例呢。如果我在 beforeEach 函数中编写 fixture.detectChanges ,那么所有测试用例都失败了。尽管我在第三个测试用例中模拟了一个 api 调用。 @拉玛娜
-
尝试在第二个测试中使用有效数据模拟 API 响应,它应该可以通过。
-
嘿,我只是照你说的做了。现在所有的测试用例都通过了,组件的覆盖率达到了 98%,这是完美的。我在下面分享测试文件。这是正确的写作方式吗?请告诉我@Ramana
标签: angular unit-testing jasmine angular-cli karma-jasmine