Error while running tests with reactive form
Asked Answered
F

1

0

I have the following code, and a few tests on it. When I mock the form for the ts tests, it works well. When I mock the same form for the html, I end up with this error:

No value accessor for form control with name: 'Enable'

If I remove this line formControlName="Enable" then the tests pass but the code breaks`.

The code is not mine, I entered it to write a minor fix and am only testing the code I touched (specifically the buttons logic).

Anyone have a solution for this error?


<ng-template matStepLabel>Label</ng-template>
<form *ngIf="form" novalidate [formGroup]="form">
  <div>
    <div class="form-item-wrapper">
      <div class="form-item">
        <label class="form-label mandatory" for="Description"
          >Description</label
        >
        <custom-input
          [type]="'text'"
          [name]="'Description'"
          [required]="'required'"
          [field]="field('Description')"
          [formGroup]="form"
          [maxLength]="200"
        ></custom-input>
      </div>
    </div>

    <div class="form-item-wrapper">
      <div class="form-item">
        <label class="form-label mandatory" for="FirstItem"
          >First Item
          <i
            class="icon-info__new"
            matTooltip="First Item"
          ></i
        ></label>
        <custom-input
          [type]="'text'"
          [name]="'FirstItem'"
          [required]="'required'"
          [field]="field('FirstItem')"
          [formGroup]="form"
          [maxLength]="255"
        ></custom-input>
      </div>
    </div>

    <div class="form-item-wrapper">
      <div class="form-item">
        <label class="form-label mandatory" for="SecondItem"
          >Second Item
          <i
            class="icon-info__new"
            matTooltip="Second Item"
          ></i>
        </label>
        <custom-input
          [type]="'number'"
          [name]="'ThirdItem'"
          [required]="'required'"
          [field]="field('ThirdItem')"
          [formGroup]="form"
        ></custom-input>
      </div>
    </div>

    <div class="form-item-wrapper">
      <div class="form-item">
        <label class="form-label">Enable </label>
        <mat-slide-toggle
          [color]="slideColor"
          formControlName="Enable"
          name="Enable"
        ></mat-slide-toggle>
      </div>
    </div>

    <div class="button-section">
      <custom-button (click)="backButtonClicked()" *ngIf="editMode != eEditMode.Edit" >
        Back
      </custom-button>
      <custom-button (click)="nextButtonClicked()" [disabled]="!form.valid" >
        Next
      </custom-button>
      <custom-button
        (click)="submit()"
        *ngIf="editMode == eEditMode.Edit"
        [theme]="'submit'"
        [disabled]="!form.valid"
      >
        Save
      </custom-button>
    </div>
  </div>
</form>

This is the code I have used in my tests to mock the valid state and call the button. Please note that identical code works in another component with the same buttons but without the form ngIf at the start.

  function clickButton(text:string){


    // Find all custom buttons within .button-section
    const buttons = debugElement.nativeElement.querySelectorAll('.button-section custom-button');

    console.log('buttons basic', buttons)

    // Iterate through the buttons and find the one with text
    let clickButton;
    for (const button of buttons) {
      console.log('button text',button.textContent)
      if (button.textContent.includes(text)) {
        clickButton = button;
        break;
      }
    }
    expect(clickButton).toBeTruthy();
    clickButton.click();
  }
  function setFormValidity(valid:boolean){

    // Create a mock form group with a valid property set to true or false
    const mockFormGroup = fb.group({
      Enable:fb.control(true)
    });

    // Set the valid property of the form group to the value of valid
    Object.defineProperty(mockFormGroup, 'valid', { get: () => valid });

    // Assign the mock form group to the component's form property
    component.form = mockFormGroup;
  }

And this is how I call it from within the test

  setFormValidity(true);
      fixture.detectChanges();

      clickButton('Back');
Fated answered 6/9, 2023 at 14:30 Comment(0)
F
0

So it turns out that the missing line was an import into the test file. As soon as I added MatSlideToggleModule to the imports, the problem was resolved.

 imports: [ReactiveFormsModule, MatSlideToggleModule]
Fated answered 7/9, 2023 at 12:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.