加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么反应式控件的更改事件不会在Jasmine Angular单元测试中触

发布时间:2020-12-17 17:11:45 所属栏目:安全 来源:网络整理
导读:我有一个更改函数,我将传递给一个响应式窗体控件的更改事件,该控件评估脏状态并检查控件上是否有任何错误,如果是,则将布尔标志设置为true / false.然后使用该布尔标志来确定是否显示 div包含错误消息的元素.这在浏览器中运行得很好,但是当单元测试运行时,“
我有一个更改函数,我将传递给一个响应式窗体控件的更改事件,该控件评估脏状态并检查控件上是否有任何错误,如果是,则将布尔标志设置为true / false.然后使用该布尔标志来确定是否显示< div>包含错误消息的元素.这在浏览器中运行得很好,但是当单元测试运行时,“脏”永远不会被设置为true.这是我的代码:

HTML

<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');
    });
}));

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

解决方法

在您的示例中,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');
    });
  }));

我还找到了解决方案的修复程序 – 只需在detectChanges之前调用age.markAsDirty():

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,请查看它.希望这些解决方案对您有所帮助:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读