这是我的问题:
我有一个自定义组件,其中包含一个带有ngModel的模板。
import { Component, Input, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
const listaMesi = [
{
value: '01',
text: 'Gennaio'
}, {
value: '02',
text: 'Febbraio'
}, {
value: '03',
text: 'Marzo'
}, {
value: '04',
text: 'Aprile'
}, {
value: '05',
text: 'Maggio'
}, {
value: '06',
text: 'Giugno'
}, {
value: '07',
text: 'Luglio'
}, {
value: '08',
text: 'Agosto'
}, {
value: '09',
text: 'Settembre'
}, {
value: '10',
text: 'Ottobre'
}, {
value: '11',
text: 'Novembre'
}, {
value: '12',
text: 'Dicembre'
}
]
const annoCorrente = new Date().getFullYear();
@Component({
selector: 'seg-month-picker',
templateUrl: './month-picker.component.html',
styleUrls: ['./month-picker.component.scss'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MonthPickerComponent),
multi: true
}]
})
export class MonthPickerComponent implements ControlValueAccessor {
private propagateChange: Function;
private checkedValue: string;
private isDisabled = true;
public meseSelezionato: string;
public annoSelezionato: string;
public yearList = [];
public monthList = listaMesi;
private _min: string;
private _max: string;
@Input() set min(value: string) {
this._min = value;
if (value) {
const [ year, month ] = value.split('-');
const maxYear = this._max ? +this._max.slice(0, 4) : annoCorrente;
this.yearList = Array.from({ length: maxYear + 1 - +year }).map((_, index) => +year + index);
}
}
get min() {
return this._min;
}
@Input() set max(value: string) {
this._max = value;
if (value) {
const [ maxYear, month ] = value.split('-');
const year = this._min ? +this.min.slice(0, 4) : annoCorrente;
this.yearList = Array.from({length: +maxYear - year + 1}).map((_, index) => year + index);
}
}
get max() {
return this._max;
}
updateYear(year: string) {
this.annoSelezionato = year;
this.updateValue();
}
updateMonth(month: string) {
this.meseSelezionato = month;
this.updateValue();
}
updateValue() {
if (this.annoSelezionato && this.meseSelezionato && this.propagateChange) {
this.propagateChange(`${this.annoSelezionato}-${this.meseSelezionato}`);
}
}
writeValue(yearMonth: string): void {
const [ year, month ] = yearMonth.split('-');
this.annoSelezionato = year;
this.meseSelezionato = month;
}
registerOnChange(fn: Function): void {
this.propagateChange = fn;
}
registerOnTouched(fn: Function): void { }
setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
}
}

<div>
<select id="anno" name="anno" [ngModel]="annoSelezionato" (ngModelChange)="updateYear($event)">
<option *ngFor="let anno of yearList" [value]="anno.value">{{anno.value}}</option>
</select>
<select id="mese" name="mese" [ngModel]="meseSelezionato" (ngModelChange)="updateMonth($event)">
<option *ngFor="let mese of monthList" [value]="mese.value">{{mese.text}}</option>
</select>
</div>
&#13;
问题是:我如何在单元测试中跟踪ngModule的变化?我将粘贴我的单元测试,但不能正常工作;我试过@viewChild(),但我肯定有问题。
import { Component, ViewChild } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { MonthPickerComponent } from './month-picker.component';
@Component({
selector: 'seg-month-picker',
template: `<seg-month-picker>`
})
export class TestComponent {
@ViewChild(MonthPickerComponent) picker;
}
function getComponent(): Promise<TestComponent> {
const fixture = TestBed
.createComponent(TestComponent);
fixture.detectChanges();
return fixture.whenStable().then(() => fixture.componentInstance);
}
describe('MonthPickerComponent', async() => {
let component: MonthPickerComponent;
let fixture: ComponentFixture<MonthPickerComponent>;
let element: HTMLElement;
const mockedComponent = await getComponent();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MonthPickerComponent, mockedComponent],
imports: [FormsModule]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MonthPickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
describe('setMin', () => {
it('deve impostare la lista di anni in base al minimo dato', () => {
component.min = '2014-03';
fixture.detectChanges();
expect(component.yearList).toEqual([2014, 2015, 2016, 2017]);
})
});
describe('getMin', () => {
it('deve restituire l\'anno minimo della lista', () => {
component.min = '2014-03';
fixture.detectChanges();
const result = component.min;
expect(result).toBe('2014-03');
});
it('deve restituire null se non ho un valore minimo', () => {
component.min = undefined;
fixture.detectChanges();
const result = component.min;
expect(result).toBe(undefined);
})
});
describe('setMax', () => {
it('deve restituire la lista di anni in base al massimo dato', () => {
component.max = '2018-01';
fixture.detectChanges();
expect(component.yearList).toEqual([2017, 2018]);
});
it('deve restituire la lista di anni in base al range dato', () => {
component.max = '2018-01';
component.min = '2014-01';
fixture.detectChanges();
expect(component.yearList).toEqual([2014, 2015, 2016, 2017, 2018]);
});
});
describe('getMax', () => {
it('deve restituire l\'anno massimo della lista', () => {
component.max = '2018-01';
fixture.detectChanges();
const result = component.max;
expect(result).toBe('2018-01');
});
it('deve restituire null se non ho un valore massimo', () => {
component.max = undefined;
fixture.detectChanges();
const result = component.max;
expect(result).toBe(undefined);
});
});
describe('writeValue', () => {
fit('deve modificare il valore all\'ngModel del componente', async () => {
console.log(mockedComponent.picker);
mockedComponent.picker.writeValue('2016-03');
fixture.detectChanges();
const result = component.max;
expect(result).toBe('2018-01');
});
it('deve restituire null se non ho un valore massimo', () => {
component.max = undefined;
fixture.detectChanges();
const result = component.max;
expect(result).toBe(undefined);
});
});
});
&#13;
问题是我必须从组件控制器测试writeValue()
函数和其他函数,跟踪ngModel假设的值。我真的不知道如何解决这个问题。
谢谢你的帮助!
---编辑---
至少我可以在组件视图中对<select>
进行html引用,并以编程方式更改其值,但我认为这是一种更好的方法。
答案 0 :(得分:0)
试试这个:
import { Component, Input, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
const listaMesi = [
{
value: '01',
text: 'Gennaio'
}, {
value: '02',
text: 'Febbraio'
}, {
value: '03',
text: 'Marzo'
}, {
value: '04',
text: 'Aprile'
}, {
value: '05',
text: 'Maggio'
}, {
value: '06',
text: 'Giugno'
}, {
value: '07',
text: 'Luglio'
}, {
value: '08',
text: 'Agosto'
}, {
value: '09',
text: 'Settembre'
}, {
value: '10',
text: 'Ottobre'
}, {
value: '11',
text: 'Novembre'
}, {
value: '12',
text: 'Dicembre'
}
]
const annoCorrente = new Date().getFullYear();
@Component({
selector: 'seg-month-picker',
templateUrl: './month-picker.component.html',
styleUrls: ['./month-picker.component.scss'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MonthPickerComponent),
multi: true
}]
})
export class MonthPickerComponent implements ControlValueAccessor {
private propagateChange: Function;
private checkedValue: string;
private isDisabled = true;
public meseSelezionato: string;
public annoSelezionato: string;
public yearList = [];
public monthList = listaMesi;
private _min: string;
private _max: string;
@Input() set min(value: string) {
this._min = value;
if (value) {
const [ year, month ] = value.split('-');
const maxYear = this._max ? +this._max.slice(0, 4) : annoCorrente;
this.yearList = Array.from({ length: maxYear + 1 - +year }).map((_, index) => +year + index);
}
}
get min() {
return this._min;
}
@Input() set max(value: string) {
this._max = value;
if (value) {
const [ maxYear, month ] = value.split('-');
const year = this._min ? +this.min.slice(0, 4) : annoCorrente;
this.yearList = Array.from({length: +maxYear - year + 1}).map((_, index) => year + index);
}
}
get max() {
return this._max;
}
updateYear(year: string) {
this.annoSelezionato = year;
this.updateValue();
}
updateMonth(month: string) {
this.meseSelezionato = month;
this.updateValue();
}
updateValue() {
if (this.annoSelezionato && this.meseSelezionato && this.propagateChange) {
this.propagateChange(`${this.annoSelezionato}-${this.meseSelezionato}`);
}
}
writeValue(yearMonth: string): void {
const [ year, month ] = yearMonth.split('-');
this.annoSelezionato = year;
this.meseSelezionato = month;
}
registerOnChange(fn: Function): void {
this.propagateChange = fn;
}
registerOnTouched(fn: Function): void { }
setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
}
}
&#13;