title: Unit tests in Angular can't read property
body: <p>I have a next component with a form for sign-up writed on Angular 9.1 </p>
  
  <pre><code>import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
  import { FormBuilder, Validators, FormGroup, FormControl, FormGroupDirective, NgForm } from '@angular/forms';
  
  @Component({
    selector: 'app-sign-up-form',
    templateUrl: './sign-up-form.component.html',
    styleUrls: ['./sign-up-form.component.scss']
  })
  export class SignUpFormComponent implements OnInit {
    @Output() submitedForm = new EventEmitter&lt;any&gt;();
    @Input() accountExist = false;
    public signUpForm: FormGroup;
    public hidePassword = true;
  
    constructor(private formBuilder: FormBuilder) {}
  
    ngOnInit() {
      this.signUpForm = this.formBuilder.group({
        email: [
          '',
          [
            Validators.required,
            Validators.pattern('^([A-z0-9_-]+\.)*[A-z0-9_-]+@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]{2,6}$')
          ]
        ],
        passwords: this.formBuilder.group({
          password: [
            '',
            [
            Validators.required,
            Validators.pattern('^[a-zA-Z0-9]{8,25}$'),
            ]
          ],
          confirmedPassword: [
            '',
            [
            Validators.required,
            Validators.pattern('^[a-zA-Z0-9]{8,25}$'),
            ]
          ]
          },
           {
            validators: [
              this.validatePasswords,
              Validators.required
            ]
          }
        )
      });
    }
  
    public onSubmit() {
      if (this.signUpForm.valid) {
        this.submitedForm.emit(this.signUpForm.value);
      }
    }
  
    public customErrorStateMatcher() {
      return {
        isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
          if (form.submitted &amp;&amp; control.parent.invalid) {
            return true;
          } else if (control.invalid &amp;&amp; control.touched) {
            return true;
          } else {
            return false;
          }
        }
      };
    }
  
    private validatePasswords(group: FormControl) {
      const password = group.get('password').value;
      const confirmPass = group.get('confirmedPassword').value;
      return password === confirmPass ? null : { notSame: true };
    }
  }
  </code></pre>
  
  <p>And there is template: </p>
  
  <pre><code>&lt;div class="sign-up"&gt;
    &lt;h2 class="sign-up__header"&gt;Sign Up&lt;/h2&gt;
    &lt;form class="sign-up__form"
          [formGroup]="signUpForm"&gt;
      &lt;div class="sign-up__form-fields-container"&gt;
        &lt;mat-form-field class="sign-up__form-field"
                        hideRequiredMarker="true"&gt;
          &lt;mat-label&gt;Email&lt;/mat-label&gt;
          &lt;input placeholder="username@example.com"
                 matInput
                 formControlName="email" /&gt;
          &lt;mat-error *ngIf="signUpForm.get('email').hasError('required')"&gt;
            You must enter a value
          &lt;/mat-error&gt;
          &lt;mat-error *ngIf="!signUpForm.get('email').hasError('required')"&gt;
            Not a valid email
          &lt;/mat-error&gt;
        &lt;/mat-form-field&gt;
        &lt;div formGroupName="passwords"&gt;
          &lt;mat-form-field class="sign-up__form-field"&gt;
            &lt;mat-label style.color="white"&gt;Enter your password&lt;/mat-label&gt;
            &lt;input matInput
                   formControlName="password"
                   [type]="hidePassword ? 'password' : 'text'" /&gt;
            &lt;mat-error *ngIf="signUpForm.get('passwords').get('password').hasError('required')"&gt;
              You must enter a value
            &lt;/mat-error&gt;
            &lt;mat-error *ngIf="!signUpForm.get('passwords').get('password').hasError('required')"&gt;
              Not a valid password
            &lt;/mat-error&gt;
            &lt;button type="button"
                    mat-icon-button
                    matSuffix
                    [attr.aria-label]="'Hide password'"
                    [attr.aria-pressed]="hidePassword"
                    (click)="hidePassword = !hidePassword"&gt;
              &lt;mat-icon *ngIf="!hidePassword"&gt;visibility&lt;/mat-icon&gt;
              &lt;mat-icon *ngIf="hidePassword"&gt;visibility_off&lt;/mat-icon&gt;
            &lt;/button&gt;
          &lt;/mat-form-field&gt;
          &lt;mat-form-field appearance="legacy"
                          class="sign-up__form-field"&gt;
            &lt;mat-label&gt;Confirm password&lt;/mat-label&gt;
            &lt;input matInput
                   type="password"
                   formControlName="confirmedPassword"
                   [errorStateMatcher]="customErrorStateMatcher()" /&gt;
            &lt;mat-error *ngIf="signUpForm.get('passwords').get('confirmedPassword').hasError('required')"&gt;
              You must enter a value
            &lt;/mat-error&gt;
            &lt;mat-error *ngIf="this.signUpForm.get('passwords').get('confirmedPassword').value.length"&gt;
              Password must match
            &lt;/mat-error&gt;
          &lt;/mat-form-field&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="sign-up__button-wrapper"&gt;
        &lt;button class="sign-up__submit"
                (click)="onSubmit()"&gt;&lt;span&gt;SUBMIT&lt;/span&gt;&lt;/button&gt;
        &lt;p *ngIf="accountExist"
           class="sign-up__custom-error"&gt;Account already exist&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="sign-up__account-exist"&gt;
        &lt;p class="sign-up__account-question"&gt;Already have an account ?&lt;/p&gt;
        &lt;a class="sign-up__sign-in-link"
           routerLink="/sign-in"&gt;Sign in&lt;/a&gt;
        &lt;a mat-button
           href="https://sportbuddies.herokuapp.com/oauth2/authorization/facebook"
           class="sign-up__facebook-btn"&gt;
          &lt;span class="sign-up__facebook-icon"&gt;&lt;/span&gt;
          &lt;span&gt;Sign up with Facebook&lt;/span&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/form&gt;
    &lt;div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>So I'm writing unit test on it with Jasmine/Karma for testing creation of components, submitting form, validations.</p>
  
  <pre><code>import { async, ComponentFixture, TestBed } from '@angular/core/testing';
  import { BrowserModule, By } from '@angular/platform-browser';
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
  import { DebugElement } from '@angular/core';
  
  import { SignUpFormComponent } from './sign-up-form.component';
  
  describe('SignUpFormComponent', () =&gt; {
    let component: SignUpFormComponent;
    let fixture: ComponentFixture&lt;SignUpFormComponent&gt;;
    let debug: DebugElement;
    let el: HTMLElement;
  
    beforeEach(async(() =&gt; {
      TestBed.configureTestingModule({
        declarations: [ SignUpFormComponent ],
        imports: [
          BrowserModule,
          FormsModule,
          ReactiveFormsModule
        ]
      })
      .compileComponents().then(() =&gt; {
        fixture = TestBed.createComponent(SignUpFormComponent);
        component = fixture.componentInstance;
        debug = fixture.debugElement.query(By.css('form'));
        el = debug.nativeElement;
      });
    }));
  
    it('should create the form', () =&gt; {
      fixture = TestBed.createComponent(SignUpFormComponent);
      const app = fixture.debugElement.componentInstance;
      expect(app).toBeTruthy();
    });
  
    it('should set submitted to true', async(() =&gt; {
      component.onSubmit();
      expect(component.signUpForm).toBeTruthy();
    }));
  
    it('should call the onSubmit method', async(() =&gt; {
      fixture.detectChanges();
      spyOn(component, 'onSubmit');
      el = fixture.debugElement.query(By.css('button')).nativeElement;
      el.click();
      expect(component.onSubmit).toHaveBeenCalledTimes(0);
    }));
  
    it('form should be invalid', async(() =&gt; {
      fixture.detectChanges();
      component.signUpForm.controls['email'].setValue('');
      component.signUpForm.controls['password'].setValue('');
      component.signUpForm.controls['confirmedPassword'].setValue('');
      expect(component.signUpForm.valid).toBeFalsy();
    }));
  
    it('form should be valid', async(() =&gt; {
      component.signUpForm.controls['email'].setValue('hello@hello.com');
      component.signUpForm.controls['password'].setValue('1234567F');
      component.signUpForm.controls['confirmedPassword'].setValue('1234567F');
      expect(component.signUpForm.valid).toBeTruthy();
    }));
  });
  </code></pre>
  
  <p>But it shows me mistakes</p>
  
  <pre><code>Failed: Cannot read property 'setValue' of undefined
  </code></pre>
  
  <p>and </p>
  
  <pre><code>Failed: Cannot read property 'controls' of undefined
  </code></pre>
  
  <p>and</p>
  
  <pre><code>Failed: Cannot read property 'valid' of undefined
  </code></pre>
  
  <p>So, why this signUpForm is undefinded and what should I do with that? Thank's.</p>