【问题标题】:Testing-library Cannot set property error of [object Object] which has only a getter测试库无法设置只有 getter 的 [object Object] 的属性错误
【发布时间】:2021-05-31 00:48:31
【问题描述】:

我在一个 Angular 应用程序中工作,我正在使用 testing-library 进行测试,这就是这种情况:

我有这个组件:

<div class="inner-card" *ngIf="!error && !loading && hasInv">
  <div class="chart-xpto">
    <abc-port-chart-donut
      *ngIf="dadosChart"
      [legenda]="true"
      [dataset]="dadosChart"
      [largura]="donutHeight"
      [altura]="donutWidth"
      identifier="chart-xpto-abc"
    ></abc-port-chart-donut>
  </div>

这是组件的 .ts:(如您所见,它扩展了 BaseComponent)

export class XptoComponent extends XptoBaseComponent implements OnInit {

这是基础组件:

export class XptoBaseComponent extends XptoCommonComponent implements OnInit {
[...]
  get error(): boolean {
    if (
      this.service.response.responseStatus === HTTP_STATUS_CODE.BAD_REQUEST ||
      this.service.response.responseStatus === HTTP_STATUS_CODE.NOT_FOUND
    ) {
      return true;
    }
    return false;
  }

  get loading(): boolean {
    return !this.service.response.responseStatus && !this.service.response.responseError;
  }

  get hasInv(): boolean {
    if (this.service.response.responseStatus === HTTP_STATUS_CODE.NO_CONTENT) {
      return false;
    }

    return true;
  }

如您所见,我需要渲染组件(错误、加载和 hasInv)的属性只是 getter,它们来自基本组件...

这就是我尝试进行测试的方式:

it('teste render', async () => {
  const {container} = await render(XptoComponent, {
    componentProperties: {
      error: false,
      loading: false,
      hasInvestment: true
    }
  })
  const abc = container.querySelector(".inner-card");
  expect(abc).toBeInTheDocument();
});

但是当我尝试以这种方式进行测试时,我

** TypeError: Cannot set property error of [object Object] which has only a getter**

所以我的问题是,如何在我的组件上设置这些属性,并能够使用 testing-library 在我的测试中正确呈现组件?

【问题讨论】:

  • 你不能,因为你还没有为这些属性定义一个setter。由于所有这些属性都依赖于服务,因此最好将服务配置为返回适当的值(作为模拟)
  • 嘿迈克!谢谢!我怎么能模拟只有吸气剂的属性?我试过这样做,但我还没有成功......
  • 你真的不能。您可以 a) 监视 getter 并返回您自己的值,或者 b) 配置一个服务模拟来为您的测试返回适当的值。
  • 我已经尝试过间谍但我也没有成功...我以这种方式尝试过间谍... jest.spyOn(XptoComponent, 'error').mockReturnValue(false)
  • 试试jest.spyOn(XptoComponent, 'error', 'get').mockReturnValue(false)

标签: javascript angular typescript angular-test testing-library


【解决方案1】:

您的属性只能获取,因此分配新值将不起作用。

但仍有一个解决方案,可能对您有用。您的 get 属性依赖于注入的服务 this.service.response.responseStatus

get error(): boolean {
    if (
      // this service can be mocked
      this.service.response.responseStatus === HTTP_STATUS_CODE.BAD_REQUEST ||
      this.service.response.responseStatus === HTTP_STATUS_CODE.NOT_FOUND
    ) {
      return true;
    }
    return false;
  }

所以不要像这里那样使用 componentProperties 设置状态:

componentProperties: {
      error: false,
      loading: false,
      hasInvestment: true
    }

您可以像这里一样提供您的服务的模拟版本:

 const {container} = await render(XptoComponent, {
    providers: [{
       provide: YourServiceType,
       useValue: { response: { responseStatus: HTTP_STATUS_CODE.NO_CONTENT } }
     }]
  })

这会影响您以所需方式获取属性的结果 ->

error: false,
loading: false,
hasInvestment: true

【讨论】:

    猜你喜欢
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 2020-09-26
    • 2020-08-29
    • 2020-09-16
    • 1970-01-01
    相关资源
    最近更新 更多