代码之家  ›  专栏  ›  技术社区  ›  J-man

茉莉花角单位试验中反应式控制不点火的变化事件是什么?

  •  4
  • J-man  · 技术社区  · 6 年前

    无功形式控制 评估 状态并检查控件上是否有任何错误,如果有,则将布尔标志设置为true/false。然后使用此布尔标志确定是否显示 <div> 具有错误消息的元素。这在浏览器中工作得很好,但是当单元测试运行时,“脏”永远不会设置为true。这是我的代码:

    <form [formGroup]="myForm" novalidate>
        <input id="age" formControlName="age" (change)="onChange()" />
        <div id="ageError" *ngIf="ageIsError()">
            <label>Age has errored</label>
        </div>
    </form>
    

    组成部分

    constructor(private fb: FormBuilder) {}
    
    ngOnInit() {
        this.myForm = this.fb.group({
            age: [null, [Validators.min(18)]]
        });
    }
    
    onChange() {
        if (this.ageIsError())
            // do something
    }
    
    ageIsError() {
        return this.myForm.controls.age.hasError('min') &&
               this.myForm.controls.age.dirty;
    }
    

    单元测试

    it('should show error message when age is less than 18', fakeAsync(() => {
        let age = component.myForm.controls.age;
        age.setValue('10', { emitEvent: true });
        fixture.detectChanges();
    
        fixture.whenStable().then(() => {
            let ageError = debugElement.query(By.css('#ageError')).nativeElement;
            expect(component.ageIsError()).toBe(true);
            expect(ageError.innerText).toContain('Age has errored');
        });
    }));
    

    同样,实际的实现在浏览器中工作,但是单元测试失败。有人知道如何在茉莉花中释放事件,以将控件设置为脏状态,还是有更好的方法来实现这一点?谢谢!

    1 回复  |  直到 5 年前
        1
  •  2
  •   shohrukh    6 年前

    在你的例子中 age.setValue(...) 实际上为输入设置了正确的值,但它没有附加 ageError 对于DOM-因为没有真实/模拟事件将控件标记为脏的。这就是为什么这个方法 ageIsError 总是返回 false 在这种情况下。

    document.createEvent('Event') 看起来效果不错:

      it('should show error message when age is less than 18', async(() => {
        const customEvent: Event = document.createEvent('Event');
        customEvent.initEvent('input', false, false);
        const ageInput = fixture.debugElement.query(By.css('input#age')).nativeElement;
        ageInput.value = 10;
        ageInput.dispatchEvent(customEvent);
    
        fixture.detectChanges();
    
        fixture.whenStable().then(() => {
          let ageError = fixture.debugElement.query(By.css('#ageError')).nativeElement;
          expect(component.ageIsError()).toBe(true);
          expect(ageError.innerText).toContain('Age has errored');
        });
      }));
    

    我也找到了解决方案-打电话 age.markAsDirty() detectChanges :

      it('should show error message when age is less than 18', async(() => {
        let age = component.myForm.controls.age;
        age.setValue('10'); // { emitEvent: true } is by default
        age.markAsDirty(); // add this line
    
        fixture.detectChanges();
    
        fixture.whenStable().then(() => {
            let ageError = fixture.debugElement.query(By.css('#ageError')).nativeElement;
            expect(component.ageIsError()).toBe(true);
            expect(ageError.innerText).toContain('Age has errored');
        });
      }));
    

    我还创造了一个 stackblitz example ,请也检查一下。希望这些解决方案能对您有所帮助:)