我尝试测试我的指令,但不是100%确定如何做。该指令控制小数分隔符,以及分隔符后允许的小数位数。它监听valueChanges,如果提供了更多的小数,它会将newValue更改回oldValue。(为简单起见,省略了指令逻辑):
@Directive({
selector: '[restrictedDecimals]'
})
export class InstrumentDecimalsDirective implements OnInit {
@Input() decimals = null;
@Input() separator = ',';
valueSubscription: Subscription;
constructor(@Self() @Optional() public ngControl: NgControl) {}
ngOnInit(): void {
this.ngControl.valueChanges.pipe(distinctUntilChanged(), pairwise()).subscribe(([oldValue, newValue]) => {
this.runCheck(oldValue, newValue);
});
}
...
}
我创建了一个名为InstrumentDecimalTestComponent
的测试组件,以便在测试中使用HTML模板:
<input type="text" restrictedDecimals decimals="2" />
和测试用例:
describe('InstrumentDecimalsDirective', () => {
let fixture: ComponentFixture<any>;
beforeEach(async () => {
const NG_CONTROL_PROVIDER = {
provide: NgControl,
useClass: class extends NgControl {
control = new FormControl();
viewToModelUpdate() {}
}
};
const testModuleMetadata: TestModuleMetadata = {
imports: [ReactiveFormsModule, FormsModule],
declarations: [InstrumentDecimalTestComponent, InstrumentDecimalsDirective]
};
fixture = TestBed.configureTestingModule(testModuleMetadata).overrideDirective(InstrumentDecimalsDirective, {
add: { providers: [NG_CONTROL_PROVIDER] },
}).createComponent(InstrumentDecimalTestComponent);
fixture.detectChanges();
});
it('should reject input with more decimals than allowed', fakeAsync(() => {
const input = fixture.debugElement.queryAll(By.directive(InstrumentDecimalsDirective))[0].nativeElement;
const inputEvent = new Event('input');
input.value = '1,12';
input.dispatchEvent(inputEvent);
input.value = '1,123';
input.dispatchEvent(inputEvent);
tick(500);
fixture.detectChanges();
expect(input.value).toBe('1,12');
}));
});
请指出缺少的部分是什么!
1条答案
按热度按时间ukdjmx9f1#
我会在这里添加一个
console.log
,如果您看不到日志,这意味着input.value =
不会触发valueChanges
。尝试将
form
或ngModel
(双向绑定)添加到InstrumentDecimalTestComponent
并更改此form
或ngModel
的值,然后查看指令中的valueChanges
是否被触发,而不是使用input.value =
更改值。此外,
NG_CONTROL_PROVIDERS
可能覆盖了关键功能。