Testing angular reactive form input value without setting formcontrol
Asked Answered
D

1

7

I have a form like this:

<form id="save_form" (ngSubmit)="save()">
    <input id="input_user" type="text" [formControl]="myForm" />
    <button type="submit">save</button>
</form>

I have a test like this:

const inputUser: HTMLInputElement = fixture.nativeElement.querySelector("#input_user");
const saveForm: DebugElement = fixture.debugElement.query(By.css("#save_form"));

inputUser.value = "Bob";
//component.myForm.setValue("Bob");

saveForm.triggerEventHandler("ngSubmit", null);

fixture.detectChanges();

In my component, the input value is not updating myForm. If I use the commented out syntax, the form is updated, but the input tag is not populated.

I am trying to simulate an input value from a user, is the formcontrol supposed to be updated through the input value in a test? I feel like if I just updated the formcontrol manually I am not simulating a user.

UPDATE:

    //component.searchUsers.setValue("Bob");
    const e: Event = document.createEvent("Event");
    e.initEvent("input", false, false);
    inputUser.value = "Bob";
    inputUser.dispatchEvent(e);
    fixture.detectChanges();

    myForm.triggerEventHandler("ngSubmit", null);
    fixture.detectChanges();
    fixture.whenStable().then(() => 
    expect(condition).toBe(true));
Deal answered 8/5, 2018 at 15:40 Comment(0)
T
5

You need to trigger change detection by dispatching a change event from the input, then detect changes. I do it as follows.

const e:Event = document.createEvent('Event');
e.initEvent('input', false, false);
inputUser.value = 'Bob';
inputUser.dispatchEvent(e);
fixture.detectChanges();
fixture.whenStable().then(() => expect(something).toEqual('something'));
Triacid answered 8/5, 2018 at 16:12 Comment(8)
so after I set input.value to "Bob", and before I triggered ngSubmit, I added those lines, but no luck. It makes sense, but that didn't seem to work. Was that what you meant?Deal
Sorry, for being unclear. Set the value in the <input>, not the FormControl. See updated answer.Triacid
Updated from a test that passes for me using @angular 5.0.2, karma ^1.7.1, & jasmine ~2.5.2.Triacid
Sorry thats gross looking, then in my component after submit: this.myForm.value comes out as null right away, and untouchedDeal
Put the expectation in a whenStable block. There's a couple rounds of change detection that have to happen.Triacid
I updated my code above, still the same issue. Your answer seems like it should work :(Deal
I'm wondering if the problem might be the call to triggerEventHandler. I call the submit method directly in my functioning tests. See the accepted answer: #47754363Triacid
I messed around a little more and wasn't able to get it to work. I appreciate your time on this, I'll check back on this thread later but for now I'm going to stick with setting the input field from the formcontrol layer (inputUser.setValue()). It seems to work flawlessly outside not 100% simulating a user. Thanks agianDeal

© 2022 - 2024 — McMap. All rights reserved.