Search code examples
javascriptangulartypescriptangular-testtesting-library

Testing-library Cannot set property error of [object Object] which has only a getter


I'm working in a Angular application and I'm using testing-library for testing, and this is the situation:

I have this component:

<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>

This is the .ts of the component: (As you can see it extends a BaseComponent)

export class XptoComponent extends XptoBaseComponent implements OnInit {

And this is the base component:

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;
  }

As you can see, the propertiers that I need to render my component (error, loading and hasInv) are only getters and they come from the basecomponent...

This is how I'm trying to do my test:

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();
});

But when I try to test in this way, I

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

So my issue is, how can I set these properties on my component and be able to render correctly the component in my test using testing-library?


Solution

  • Your properties are get only thus assigning new values wont work.

    But there is still a solution, which might work for you. Your get properties rely on an injected service 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;
      }
    

    So instead of setting the state with componentProperties like here:

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

    You could provide a mocked version of your service like here:

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

    This would affect the result of your get only properties in desired way ->

    error: false,
    loading: false,
    hasInvestment: true