I would like to test a template driven form. Initially I would like the form's button to be disabled since I want to make sure the user enters a name. This is done by the 'required' property on the name input field.
So I created the following template:
<form #form="ngForm">
<!-- note the 'required' property on the input field -->
<input
type="text"
name="name"
id="name"
#name="ngModel"
required
ngModel
/>
<button type="submit" [disabled]="form.invalid">Submit</button>
{{ form.invalid | json }}
</form>
This renders nicely in the browser:
Now I would like to test this behavior. And here is where it gets funky. The test is as follows:
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { AppComponent } from "./app.component";
import { DebugElement } from "@angular/core";
import { By } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { CommonModule } from "@angular/common";
describe("AppComponent", () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let el: DebugElement;
let button: HTMLButtonElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [CommonModule, FormsModule]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
el = fixture.debugElement;
fixture.detectChanges();
button = el.query(By.css("button")).nativeElement;
});
describe("submit button", () => {
it("should be disabled by default", () => {
expect(button.nativeNode.disabled).toBeTrue();
});
});
});
My test fails and it does not recognise the form.invalid property. It sets it to 'false':
So my best guess would be that the actual 'ng build' or 'ng serve' of the Angular application does some magic that sets the ngForm to have an invalid property if one of the input values does not match the requirements.
But how do I do this in my test?
I would like the test to be as close to the real world example. So having to set form.invalid to true manually kinda defeats the purpose of the test.
Here's a Stackblitz example of the forementioned code: https://stackblitz.com/edit/angular-ivy-pfnkfc

