セレクタでコントロールからカスタムを取得しましたapp-date-picker
。それはControlValueAccessor
を実装します。私はバインディングの両方の方向をテストしMyPage
ためのユニットテストを書くことをしようとしている角2 - ネストされたカスタムフォームコントロールへのユニットテストのバインド
<app-date-picker class="address__from-date" [(ngModel)]="fromDate"></app-date-picker>
:私は介して、このカスタムフォームコントロールを含むMyPage
と呼ばれるコンポーネントを持っています。私は、例えば、うまく他のフォームフィールドのためにこれを行っている:私は私のカスタムフォームのコントロールのためにこれを行うにしようとすると
it('should bind zip code', fakeAsync(() => {
const formControl = element.query(By.css('.address__zip-code input')).nativeElement;
// model -> view
component.zipCode = 76777;
fixture.detectChanges();
tick();
expect(formControl.value).toEqual('76777');
// view -> model
formControl.value = '89556';
formControl.dispatchEvent(new Event('input'));
expect(component.zipCode).toEqual(89556);
}));
私の問題が発生します。これまでのところ、私は唯一の結合の一つの方向をテストすることができ、そして、それはちょうどひどいですng-reflect-model
の使用、必要とされていてもよう:
it('should bind from-date', fakeAsync(() => {
const formControl = element.query(By.css('.address__from-date app-date-picker')).nativeElement;
// model -> view
component.fromDate = '01/2017';
fixture.detectChanges();
tick();
expect(formControl.attributes['ng-reflect-model'].value).toEqual('01/2017');
// view -> model
// Not sure what to do here either
}));
これを行うことについて移動する良い方法はありますか?私がしたい:私はフォームコントロールにそれを有線知っているように、
- は
ng-reflect-*
MyPage
単体テストから結合の両方の方向をテストすることができ その他の注意事項:
MyPage
成分はfromDate
(およびzipCode
)フィールドと、標準的な構成要素です。
カスタムフォームフィールドが正しくControlValueAccessor
を実装し、ngModel
を介して結合され、それ自体、date
フィールドを持っており、内部<input>
を使用しています:
<input [(ngModel)]="date" type="date">
DatePickerComponent
@Component({
selector: 'app-date-picker',
templateUrl: './date-picker.component.html',
styleUrls: ['./date-picker.component.scss'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
}]
})
export class DatePickerComponent implements ControlValueAccessor {
private propagateChange = (_: any) => {};
private _date: string;
get date(): string {
return this._date;
}
@Input()
set date(value: string) {
this._date = value;
this.propagateChange(value);
}
writeValue(newValue: any) {
if (newValue !== undefined) {
this.date = newValue;
}
}
registerOnChange(fn: any) {
this.propagateChange = fn;
}
registerOnTouched(fn: any) {
// Not used
}
}
UPDATE 8/10/2017
これまでのところ、私は@ViewChild
で欲しいものに近い得ている:
@Component(...)
MyPageComponent {
@ViewChild('fromDate') fromDatePicker: DatePickerComponent;
...
}
MyPage
テンプレートになる(テンプレート参照変数#fromDate
に注意してください):
<app-date-picker #fromDate class="address__from-date" [(ngModel)]="fromDate">
</app-date-picker>
その後、テストは次のようになります。
it('should bind from-date', fakeAsync(() => {
// model -> view
component.info.fromDate = '01/2017';
fixture.detectChanges();
tick();
expect(component.fromDatePicker.date).toEqual('01/2017');
// view -> model
component.fromDatePicker.date = '02/2017';
expect(component.info.fromDate).toEqual('02/2017');
}));
誰かがもっと良い方法を知っていますか?これは最適ではないが、これは今のところ私を得る。