【问题标题】:Not able to use the read-only property of a component in jasmine unit tests无法在 jasmine 单元测试中使用组件的只读属性
【发布时间】:2022-01-09 21:23:32
【问题描述】:

我的组件中有一个@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 没有被按需调用。如果可以提出更好的方法,将不胜感激。

【问题讨论】:

  • 发射器不用更换,测试如下:stackoverflow.com/a/62871934/3001761
  • @jonrsharpe 但正如此示例所示,我的输出发射器不会在单击时获得发射值,而是在某些 http 调用成功或失败时发射。所以我不想只触发点击来调用输出事件。
  • 是否这个例子表明了这一点?你应该触发什么点击?给minimal reproducible example
  • @jonrsharpe 我已经添加了示例代码。请检查。另外,如果可以提出一种更好的方法来避免使用 setTimeout,那就太好了。

标签: angular jasmine karma-jasmine


【解决方案1】:

您可以禁用 TypeScript 检查一行代码:

// @ts-ignore
expect(component.uploadFinished.emit).toHaveBeenCalledWith({response)

注意:我建议您只在规范文件中使用它。一般来说,这是最后的手段

【讨论】:

    【解决方案2】:

    我通过更改解决了这个问题

    component.uploadFinished = {emit: jasmine.createSpy()};
    

    spyOn(component.uploadFinished, 'emit');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-23
      • 2018-12-09
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      • 2019-07-13
      • 2018-02-15
      • 2022-07-30
      相关资源
      最近更新 更多