title: How to get/set an Ionic 2 ion-input FormControl value within a FormGroup from a Unit Test?
body: <p>I would like to write a unit test that interacts with an Angular 2/Ionic 2 ion-input field by setting values in the input field and then examining the associated instance members.</p>
  
  <p>Specifically, I would like to:</p>
  
  <ul>
  <li>set a default value in the component instance. </li>
  <li>verify that the value is set in the related DOM element.</li>
  <li>enter a value into the related DOM element (input field)</li>
  <li>verify that it is reflected in the component instance. </li>
  </ul>
  
  <p>I have this working for a normal HTML input field however there is something about the use of an ion-input field that I do understand. </p>
  
  <p>My unit test and test component:</p>
  
  <pre><code>/**
  * Form Tests
  */
  
  import {Component} from '@angular/core';
  
  import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing';
  
  import { By }              from '@angular/platform-browser';
  import { DebugElement }    from '@angular/core';
  
  import {
    AbstractControl,
    FormControl,
    FormGroup,
    FormsModule,
    ReactiveFormsModule
  } from '@angular/forms';
  
  import {dispatchEvent} from '@angular/platform-browser/testing/browser_util';
  
  // Ionic imports
  
  import { 
  
    App, 
    MenuController, 
    NavController, 
    Platform, 
    Config, 
    Keyboard, 
    Form, 
    IonicModule 
  
  } from 'ionic-angular';
  
  describe( 'Ionic Form Tests', 
    () =&gt; {
  
      // -----------------------------------
  
      /**
      * instance and element in a FormControl should match, right?
      */
  
      it( 'nativeElement and instance should match with input and ion-input in a FormGroup', 
  
        fakeAsync(() =&gt; {
  
          TestBed.configureTestingModule({
            declarations: [
              IonicFormTestComponent
            ],
            providers: [
              App,
              Platform,
              Form,
  
              { provide: Config, useClass: ConfigMock },
  
            ],
            imports: [
              FormsModule,
              IonicModule,
              ReactiveFormsModule,
            ],
          });
  
          let fixture: any = TestBed.createComponent( IonicFormTestComponent );
  
          fixture.whenStable().then(() =&gt; {
  
            fixture.detectChanges();
            tick();
  
            let instance = fixture.componentInstance;
  
            // first check that the initial plain input value and element match
  
            let plainInputEl = fixture.debugElement.query( By.css( '[formControlName="plainInputControl"]' ) ).nativeElement;
  
            expect( instance.plainInputControl.value ).toEqual( 'plain input control value' );
            expect( plainInputEl.value ).toEqual( 'plain input control value' );
  
            // now check to see if the model updates when we update the DOM element
  
            plainInputEl.value = 'updated Plain Input Control Value';
  
            dispatchEvent( plainInputEl, 'input' );
            fixture.detectChanges();
            tick();
  
            // this works
  
            expect( instance.plainInputControl.value ).toEqual( 'updated Plain Input Control Value' );
  
            // -------------------------------------------------------------
            // repeat with ion-input
  
            let ionicInputEl = fixture.debugElement.query( By.css( '[formControlName="ionicInputControl"]' ) ).nativeElement;
  
            expect( instance.ionicInputControl.value ).toEqual( 'ionic input control value' );
  
            // this fails with ionicInputEl.value 'undefined' 
            // (how to correctly get the value of the ion-input element?)
  
            expect( ionicInputEl.value ).toEqual( 'ionic input control value' );
  
            ionicInputEl.value = 'updated Ionic Input Control Value';
  
            dispatchEvent( ionicInputEl, 'input' );
            fixture.detectChanges()
            tick();
  
            console.log( "Ionic input element value is:", ionicInputEl.value );
  
            // this fails, instance.ionicInputControl.value not changed.
  
            expect( instance.ionicInputControl.value ).toEqual( 'updated Ionic Input Control Value' );
  
          });
  
        }) // end of fakeAsync()
  
      ); // end of it()
  
    }
  
  ); // end of describe()
  
  // -------------------------------------------------
  
  /**
  * ionic test component with form Group 
  */
  
  @Component({
    selector: 'ionic-form-test-component',
    template: `
      &lt;form [formGroup]="testFormGroup"&gt;
        &lt;input type="text" value="" formControlName="plainInputControl" /&gt;
        &lt;ion-input type="text" value="" formControlName="ionicInputControl"&gt;&lt;/ion-input&gt;
      &lt;/form&gt;
     `
  })
  
  export class IonicFormTestComponent {
  
    testFormGroup: FormGroup;
    plainInputControl: AbstractControl;
    ionicInputControl: AbstractControl;
  
  
    constructor() {
  
      this.testFormGroup = new FormGroup({
          'plainInputControl': new FormControl( '' ),
          'ionicInputControl': new FormControl( '' )
      });
  
      this.plainInputControl = this.testFormGroup.controls[ 'plainInputControl' ];
      this.plainInputControl.setValue( 'plain input control value' );
  
      this.ionicInputControl = this.testFormGroup.controls[ 'ionicInputControl' ];
      this.ionicInputControl.setValue( 'ionic input control value' );
  
    }
  
  }
  
  // --------------------------------------------------
  
  export class ConfigMock {
  
    public get(): any {
      return '';
    }
  
    public getBoolean(): boolean {
      return true;
    }
  
    public getNumber(): number {
      return 1;
    }
  }
  
  // END
  </code></pre>
  
  <p>How do I get/set the value of an ion-input field programmatically within a unit test so that the above works? </p>
  
  <p>Clearly I'm missing something. The Ionic 2 documentation is woefully silent on this subject. The Angular 2 documentation on FormControl seems to imply that it automatically supports two way binding (the successful unit test above seems to support that assertion.) </p>