Wie zu get/set-eine Ionic 2 ion-Eingang Control-Wert innerhalb einer FormGroup von einem Unit Test?

Ich möchte schreiben Sie einen unit test, der eine Interaktion mit einem Winkel 2/Ionic-2 Ionen-Eingabefeld, indem Sie die Werte in das Eingabefeld ein und anschließend die Prüfung des zugehörigen Instanz-Mitglieder.

Speziell möchte ich:

  • legen Sie einen Standardwert in die Instanz der Komponente.
  • stellen Sie sicher, dass der Wert wird in das zugehörige DOM-element.
  • geben Sie einen Wert in das zugehörige DOM-element (Eingabefeld)
  • stellen Sie sicher, dass er sich in die Instanz der Komponente.

Ich habe diese arbeiten, die für ein normales HTML-input Feld, aber es ist etwas über die Verwendung eines Ionen-input-Feld, das verstehe ich.

Mein unit-test und test-Komponente:

/**
* 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', 
  () => {

    //-----------------------------------

    /**
    * instance and element in a FormControl should match, right?
    */

    it( 'nativeElement and instance should match with input and ion-input in a FormGroup', 

      fakeAsync(() => {

        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(() => {

          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: `
    <form [formGroup]="testFormGroup">
      <input type="text" value="" formControlName="plainInputControl" />
      <ion-input type="text" value="" formControlName="ionicInputControl"></ion-input>
    </form>
   `
})

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

Wie bekomme ich/setzen Sie den Wert von einem ion-input-Feldes programmgesteuert innerhalb eines unit-test, so dass die oben genannten Werke?

Klar bin ich etwas fehlt. Der Ionic-2-Dokumentation ist völlig schweigt zu diesem Thema. Die Eckige 2-Dokumentation auf der FormControl scheint zu implizieren, dass es automatisch unterstützt zwei-Wege-Bindung (die erfolgreichen unit-test oben scheint die Unterstützung für diese Behauptung.)

 

One Reply
  1. 4

    Nach viel Versuch und Irrtum, es stellt sich heraus, dass, um Ionic 2 zu erkennen, die ion-input-Feld der Wert geändert hat, der Wert des ersten child-element des ion-input, der ein input-Feld gesetzt werden, und dann ein ‚input‘ event muss ausgelöst werden, die auf das element.

    //change the value of the element
    
    ionicInputEl.children[0].value = "ELEMENT UPDATE";
    
    dispatchEvent( ionicInputEl.children[0], 'input' );
    fixture.detectChanges();
    tick();
    
    //check to see that the instance value updated to match.
    
    expect( instance.ionicInputControl.value ).toEqual( 'ELEMENT UPDATE');
    

    Greifen in die innere Struktur der Ionen-Eingabefeld ist hässlich also habe ich ihm ein Thema darüber: https://github.com/driftyco/ionic/issues/9622

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.