Jest.js 测试Angular 指令和触发值变更

ruarlubt  于 2023-02-20  发布在  Jest
关注(0)|答案(1)|浏览(165)

我尝试测试我的指令,但不是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');
   }));

});

请指出缺少的部分是什么!

ukdjmx9f

ukdjmx9f1#

我会在这里添加一个console.log,如果您看不到日志,这意味着input.value =不会触发valueChanges

this.ngControl.valueChanges.pipe(distinctUntilChanged(), pairwise()).subscribe(([oldValue, newValue]) => {
            console.log('value changes triggered !!');
            this.runCheck(oldValue, newValue);
        });

尝试将formngModel(双向绑定)添加到InstrumentDecimalTestComponent并更改此formngModel的值,然后查看指令中的valueChanges是否被触发,而不是使用input.value =更改值。
此外,NG_CONTROL_PROVIDERS可能覆盖了关键功能。

相关问题