Search code examples
angularjasminekarma-jasminekarma-runnerangular-test

Error in default test CAse:Cannot read properties of undefined (reading 'username')


Getting Error in default test case. My component has a Reactive form with NgModel binding to display Data as well as read the updated data in the form.

While executing the spec while, I am getting error in create component Test case for the first input of form. pasting my code here.

HTML File

        <form [formGroup]="editUserFrom">
      <div>
        <label for="username">User Name</label>
        <input
          type="text"
          id="username"
          formControlName="username"
          [(ngModel)]="editableUserData.username"
        />
      </div>
      <div>
        <label for="name">Name</label>
        <input
          type="text"
          id="name"
          formControlName="name"
          [(ngModel)]="editableUserData.name"
        />
      </div>
      <div>
        <label for="email">Email </label>
        <input
          type="text"
          id="email"
          formControlName="email"
          [(ngModel)]="editableUserData.email"
        />
      </div>
      <div formGroupName="address">
        Address
        <div class="form-group">
          <label for="street">Street</label>
          <input
            type="text"
            name="street"
            formControlName="street"
            [(ngModel)]="editableUserData.address.street"
          />
        </div>
        <div class="form-group">
          <label for="suite">Suite</label>
          <input
            type="text"
            name="suite"
            formControlName="suite"
            [(ngModel)]="editableUserData.address.suite"
          />
        </div>
        <div class="form-group">
          <label for="city">City</label>
          <input
            type="text"
            name="city"
            formControlName="city"
            [(ngModel)]="editableUserData.address.city"
          />
        </div>
        <div class="form-group">
          <label for="zipcode">Pin Code</label>
          <input
            type="text"
            name="zipcode"
            formControlName="zipcode"
            [(ngModel)]="editableUserData.address.zipcode"
          />
        </div>
      </div>
      <div>
        <button type="submit" (click)="onSubmiteditUser()">Submit</button>
      </div>
    </form>

TS File

export class EdituserComponent implements OnInit {
  existingUsers: any;
  editableUserData: any = {};
  editableUserService: any;

 editUserFrom = new FormGroup({
username: new FormControl(),
name: new FormControl(),
email: new FormControl(),
address: new FormGroup({
  suite: new FormControl(),
  street: new FormControl(),
  city: new FormControl(),
  zipcode: new FormControl(),
}),
 });

  ngOnInit(): void {
this.editableUserService = this.userService.editUserSubject.subscribe(
  (user: any) => {
    this.editableUserData = user[user.length - 1];
  }
);
}

  constructor(
private userService: UserserviceService,
private router: Router
  ) {}
}

Spec File

     fixture = TestBed.createComponent(EdituserComponent);
  component = fixture.componentInstance;

  fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
  });

Error in Karma TypeError: Cannot read properties of undefined (reading 'username')

I am trying to build a dummy Angular project to learn and Implement Unit testing on it.

I have an edit component which is receive a user details via Behavioural Subject (Dashboard Component display all the users on click of single user it will route us to EditComponent(which is a child component of Dashboard).


Solution

  • make sure your behaviour subject is initialized with the default value of {}.

    Because the behaviour subject will trigger the subscribe on load of component, if it is not an object or has null or undefined. Then accessing the property username of undefined, will throw an error, which is believe is your issue.

    editUserSubject: BehaviourSubject<any> = new BehaviourSubject<any>({ address: {} });
    

    Another simply way to get rid of the error, is to default the value to {}, if the value accessed is falsy inside subscribe.

    ngOnInit(): void {
      this.editableUserService = this.userService.editUserSubject.subscribe(
        (user: any) => {
          this.editableUserData = user?.[user.length - 1] || { address: {} }; // <- changed here!
        }
      );
    }