无法在 jasmine 单元测试中使用组件的只读 属性
Not able to use the read-only property of a component in jasmine unit tests
我的组件中有一个 @Output 事件发射器,为了测试它发出的值,我做了这样的事情:
component.uploadFinished = {emit: jasmine.createSpy()};
---
---
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response: jasmine.any(HttpResponse)})
这里不允许我写 component.uploadFinished 因为它说它是只读的 属性。
任何帮助将不胜感激。
这里的组件也是 TestComponent
类型
编辑 1:
这是我的 ts 文件和我正在为其编写测试的函数
async fileUpload() {
this.fileUploadStatus = 'uploading';
const file = this.uploadFile[0];
const formData = new FormData();
formData.append(this.uploadConfig.fieldName, file, file.name);
const req = new HttpRequest(this.uploadConfig.method, this.uploadConfig.url, formData, {
headers: this.uploadConfig.headers
});
try {
const response = await this.http.request(req).pipe(
retry(3)
).toPromise() as HttpResponse<any>;
this.fileUploadStatus = 'success';
this.uploadFinished.emit({response});
} catch (error) {
this.uploadFinished.emit({error});
}
}
这是单元测试
it('should emit success response', async () => {
component.uploadFinished = {emit: jasmine.createSpy()};
// eslint-disable-next-line max-len
component.uploadConfig = {
method: 'POST',
url: '/api/attachments',
fieldName: 'file',
// eslint-disable-next-line @typescript-eslint/naming-convention
headers: new HttpHeaders({ 'Accept': 'application/json' })
};
component.handleFiles(createFileList(['matching.fmwr']));
fixture.detectChanges();
component.fileUpload(); // trigger upload
// mock request
const attachment = { id: 201, fileName: 'matching.fmwr' };
const req = httpMock.expectOne('/api/attachments');
req.flush(attachment);
httpMock.verify();
// api call is async function and there is time delay in emit
await (new Promise((resolve, reject) => {
setTimeout(()=>{
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response: jasmine.any(HttpResponse)})
return resolve(true);
}, 1000);
}))
});
我必须使用 setTimeout,因为异步函数 emit 没有按需要被调用。如果可以建议更好的方法,我们将不胜感激。
您可以禁用 TypeScript 检查一行代码:
// @ts-ignore
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response)
注意:我建议您只在规范文件中使用它。总的来说这是最后的手段
我通过更改
解决了这个问题
component.uploadFinished = {emit: jasmine.createSpy()};
至
spyOn(component.uploadFinished, 'emit');
我的组件中有一个 @Output 事件发射器,为了测试它发出的值,我做了这样的事情:
component.uploadFinished = {emit: jasmine.createSpy()};
---
---
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response: jasmine.any(HttpResponse)})
这里不允许我写 component.uploadFinished 因为它说它是只读的 属性。 任何帮助将不胜感激。 这里的组件也是 TestComponent
类型编辑 1:
这是我的 ts 文件和我正在为其编写测试的函数
async fileUpload() {
this.fileUploadStatus = 'uploading';
const file = this.uploadFile[0];
const formData = new FormData();
formData.append(this.uploadConfig.fieldName, file, file.name);
const req = new HttpRequest(this.uploadConfig.method, this.uploadConfig.url, formData, {
headers: this.uploadConfig.headers
});
try {
const response = await this.http.request(req).pipe(
retry(3)
).toPromise() as HttpResponse<any>;
this.fileUploadStatus = 'success';
this.uploadFinished.emit({response});
} catch (error) {
this.uploadFinished.emit({error});
}
}
这是单元测试
it('should emit success response', async () => {
component.uploadFinished = {emit: jasmine.createSpy()};
// eslint-disable-next-line max-len
component.uploadConfig = {
method: 'POST',
url: '/api/attachments',
fieldName: 'file',
// eslint-disable-next-line @typescript-eslint/naming-convention
headers: new HttpHeaders({ 'Accept': 'application/json' })
};
component.handleFiles(createFileList(['matching.fmwr']));
fixture.detectChanges();
component.fileUpload(); // trigger upload
// mock request
const attachment = { id: 201, fileName: 'matching.fmwr' };
const req = httpMock.expectOne('/api/attachments');
req.flush(attachment);
httpMock.verify();
// api call is async function and there is time delay in emit
await (new Promise((resolve, reject) => {
setTimeout(()=>{
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response: jasmine.any(HttpResponse)})
return resolve(true);
}, 1000);
}))
});
我必须使用 setTimeout,因为异步函数 emit 没有按需要被调用。如果可以建议更好的方法,我们将不胜感激。
您可以禁用 TypeScript 检查一行代码:
// @ts-ignore
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response)
注意:我建议您只在规范文件中使用它。总的来说这是最后的手段
我通过更改
解决了这个问题component.uploadFinished = {emit: jasmine.createSpy()};
至
spyOn(component.uploadFinished, 'emit');