Monday, 6 January 2020

UT not pass due to undefined FormArray control while the control must be defined

I have a workshop-edit component that (in order):

  • Build the form
  • Retrieve the workshop to edit
  • Update form values with workshop values

Here is the code:

ngOnInit() {
  this.buildForms();
  this.initialize();
}

async initialize(): Promise<void> {
  const id = this.route.snapshot.params.id;

  this.workshop = await this.workshopService.find(id); // in real this is in a trycatch block
  this.updateFormValues();
}

buildForms(): void {
  this.form = ... // not important, this is not the problem
  this.discussesForm = this.formBuilder.group({
    array: this.formBuilder.array([], Validators.required),
  });
}

updateFormValues(): void {
  this.form.patchValue(this.workshop);
  this.workshop.ListDebates.forEach((discussion, index) => {
    this.addDiscussion();
    (this.discussesForm.get('array') as FormArray).at(index).patchValue({ // This line will throw error while UT.
      title: discussion.Title, description: discussion.Description, key: discussion.Key,
    });
  });
}

addDiscussion(): void {
  (this.discussesForm.get('array') as FormArray).push(this.formBuilder.group({
    title: [null],
    description: [null],
    key: [null],
  });
}

workshop.ListDebates look like:

[
  {
    Key: 1,
    Title: 'title',
    Description: 'description',
  },
]

So, all the code above works fine, but i'm trying to unit test the updateFormValues method.

This is what I tried:

it('should update form values', () => {
  spyOn(component, 'addDiscussion');
  component.workshop = { Title: 'fake title', ListDebates: [
    { Key: 1, Title: 'fake', Description: 'fake' },
    { Key: 2, Title: 'fake', Description: 'fake' },
  ]} as any as IColabEvent;
  component.updateFormValues();
  expect(component.form.value.Title).toEqual('fake title'); // test OK
  expect((component.discussesForm.get('array') as FormArray).controls.length).toEqual(2); // test KO, expected 0 to be 2
  expect((component.discussesForm.get('array') as FormArray).at(0).value).toEqual(...); // test KO (not runned)
});

Everytime I get error: Cannot read property 'patchValue' of undefined (in the updateFormValues method).

I've tried lots of things (and random things like adding fixture.detectChanges()) but I don't find a way to fix it.

What is weird is that addDiscussion is called 2 times, so I wonder why my FormArray control is undefined.

I've console.log() some things and it look like addDiscussion is called but isn't pushing a group like it must does.

I repeat myself but in the real app it's working as intended.



from UT not pass due to undefined FormArray control while the control must be defined

No comments:

Post a Comment