web-dev-qa-db-ja.com

Angularテスト:FormControl valueChanges Observable

テキスト入力があり、変更を聞いています。

コンポーネント

_name = new FormControl('',Validators.required);

ngOnInit() {
  this.data = 'oldvalue';
  this.checkName();
}

checkName() {
  this.name.valueChanges.subscribe(val=>{
     console.log(val);
     this.data= "newvalue"; // updating Value
  });
}
_

[〜#〜] html [〜#〜]

_<input name="name" formControlName="name">
_

これまでの私の試み:

component.spec.ts

_it('should test data field ', () => {
    const fixture = TestBed.createComponent(UserComponent);
    const app=fixture.debugElement.componentInstance;
    const el = fixture.nativeElement.querySelector('input');
    el.value ='something';
    dispatchEvent(new Event(el));
    fixture.detectChanges();
    fixture.whenStable().then(()=>{expect(app.data).toBe('newvalue');
});
_

問題:入力フィールドにデータが入力されていても、サブスクライブコールバック内のコードは実行されません。

それは常に示しています:

'oldvalue'は 'newvalue'である必要があります。

私もsetValue()メソッドを試しましたが、うまくいきませんでした。それはサブスクライブコールバック内に決して入りません

_app.name.setValue('vikas');
fixture.detectChanges();
fixture.whenStable().then(()=>{expect(app.data).toBe('newvalue');
_

私は Angular 2 test 内からの入力HTMLフィールドの更新と= Angular2コンポーネント:フォーム入力値の変更のテスト を参照しましたが、運がありません:(

何が欠けていますか?

10
Vikas

一見すると、コントロール名を_@Input_として取るFormControlNameディレクティブを使用しているため、FormControlが入力に接続されていないという事実を見逃していると思います。

FormControlをテストする場合は、FormControlDirectiveを_@Input_として取るFormControlを検討できます。

_<input name="name" [formControl]="name">
                                  ^^^^^
                      `name` is FormControl instance here not string
_

これで、入力のテキストを変更するたびに、FormControlが変更をトリガーするようになります。しかし、そのようなテンプレートを書くとすぐに、angularはテストでReactiveFormsModule依存関係を尋ねます:

_import { ReactiveFormsModule } from '@angular/forms';
....

TestBed.configureTestingModule({
   imports: [
     ReactiveFormsModule  <=== add this
   ],
   declarations: [TestComponent],
});
_

今あなたのテストに関して。

1)TestBedfixture.detectChanges()を呼び出してデータバインディングを実行するように指示する必要があります。

_const fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); <== add this
_

2)入力時に変更を正しく実行する必要があります:

_el.dispatchEvent(new Event('input'));
_

コード全体は次のとおりです。

_it('should display original title', () => {
  const fixture = TestBed.createComponent(TestComponent);
  fixture.detectChanges();
  const app = fixture.debugElement.componentInstance;
  const el = fixture.nativeElement.querySelector('input');
  el.value = 'something';
  el.dispatchEvent(new Event('input'));
  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(app.data).toBe('newvalue');
  });
});
_

Plunkerの例

17
yurzui