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');