Reputation: 933
I have a workshop-edit component that (in order):
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.
Upvotes: 0
Views: 241
Reputation: 8650
Rather than something being wrong with your test cases, it is in fact your code that has an issue. There is no need for you to use addDiscussion
first to create an object with null
values and then use patchValue
to set the values. Instead, set the values as you create the form group itself. Change your addDiscussion
function to accept the discussion
parameter.
addDiscussion(discussion = {}): void {
this.discussesForm.get('array').push(this.formBuilder.group({
title: discussion.Title || null,
description: discussion.Description || null,
key: discussion.Key || null
}));
}
Then in updateFormValues
, in your foreach
loop, get rid of the patchValue
code and pass discussion
instead.
this.workshop.ListDebates.forEach(discussion => {
this.addDiscussion(discussion);
});
Apart from this, as already mentioned in the comments, the addDiscussion
no longer needs to be spied upon since your test depends on it. Once this is done, your tests should be working.
Upvotes: 1