【问题标题】:Value changes not firing in an angular unit test值更改未在角度单元测试中触发
【发布时间】:2022-01-19 21:34:07
【问题描述】:

我正在尝试对表单输入之间的绑定进行单元测试,即语音电话号码和短信电话号码。期望的行为是输入语音电话号码也应该填充短信电话号码,但我正在努力为此功能编写单元测试。

如你所见,到目前为止我是否尝试过很多东西:

  • 使用 fakeAsync
  • 修补 Value 并通过 nativeElement.value 路由提供值。
  • component.ContactForm.updateValueAndValidity() 函数触发更改事件
  • 尝试控制台在期望之前记录语音电话号码的 val 我可以 看到值已成功修补,但是 valueChanges 仍然没有被触发 并且测试不断失败。

beforeEach(() => {
  fixture = TestBed.createComponent(ContactAddEditComponent);
  fixture.detectChanges();
  component = fixture.componentInstance;
  component.ContactForm = new FormGroup({
    FirstName: new FormControl(''),
    LastName: new FormControl(''),
    VoicePhoneNumber: new FormControl('', Validators.required),
    // SMSPhoneNumber: ['', Validators.compose([Validators.required, Validators.maxLength(10), Validators.minLength(10)])],
    SMSPhoneNumber: new FormControl('', Validators.required),
    Email: new FormControl('', Validators.required),
    groups: new FormControl([]),
    channel: new FormControl(0, Validators.required)
  });
  fixture.detectChanges();
});

it('should create', () => {
  expect(component).toBeTruthy();
});

it('Entering VoicePhoneNumber should also populate SMSPhoneNumber ', () => {
  component.ContactForm.patchValue({
    VoicePhoneNumber: "(647) 704-3898"
  });
  // const voiceNumberInput = fixture.debugElement.query(By.css('#voiceNumberInput')).nativeElement;
  // const smsNumberInput = fixture.debugElement.query(By.css('#smsNumberInput')).nativeElement;
  // voiceNumberInput.value = '(647) 704-XXXX'
  // voiceNumberInput.dispatchEvent(new Event('input'));
  // tick(3000);
  component.ContactForm.updateValueAndValidity();

  fixture.detectChanges();
  console.log(component.ContactForm.controls.VoicePhoneNumber.value);
  console.log(component.ContactForm.controls.SMSPhoneNumber.value);
  // console.log(smsNumberInput.value);
  expect(component.ContactForm.controls.SMSPhoneNumber.value).toBe(component.ContactForm.controls.VoicePhoneNumber.value);
  // const smsNumberInput = fixture.debugElement.query(By.css('#smsNumberInput')).nativeElement;
  // console.log(smsNumberInput.value);
})

component.ts 中的一部分,应该被执行以使测试成功

async ngOnInit() {
 this.ContactForm.get('VoicePhoneNumber').valueChanges.subscribe(value => {
      //console.log(value)
      if (value != null) {
        let voicelen = value.replace(/[^a-zA-Z0-9 ]/g, "").replace(" ", '');
        let smslen = this.f.SMSPhoneNumber.value.replace(/[^a-zA-Z0-9 ]/g, "").replace(" ", '').length;
        //console.log(this.f.SMSPhoneNumber.value);
        if (smslen == 0 && voicelen.length == 10) {
          this.voiceNumberEntered = true;
          this.ContactForm.patchValue({
            SMSPhoneNumber: value
          });
        }
      }
    });
}

【问题讨论】:

    标签: javascript angular typescript unit-testing jasmine


    【解决方案1】:

    您在ngOnInit 方法中订阅。 fixture.detectChanges(); 触发它。由于您在调用 ngOnInit 之前对 ContactForm 进行了更改,因此您不会收到该事件。

      component.ngOnInit(); // <== this before updating form
      component.ContactForm.patchValue({
        VoicePhoneNumber: "(647) 704-3898"
      });
      tick(); // <== this to wait for the subscribe to trigger
      expect(component.ContactForm.controls.SMSPhoneNumber.value).toBe(component.ContactForm.controls.VoicePhoneNumber.value);
    

    【讨论】:

    • 嗨我试过这个解决方案,你说的确实有道理。所以,谢谢你的解释。但是在尝试我得到的解决方案时。错误:未捕获(承诺中):TypeError:无法读取 null 的属性(读取“替换”)
    • 这意味着你在做myVar.replace,编译器说myVar is null。我猜this.f.SMSPhoneNumber 是空的
    猜你喜欢
    • 2019-02-19
    • 2017-08-06
    • 1970-01-01
    • 2018-01-08
    • 2021-07-06
    • 2020-08-26
    • 1970-01-01
    • 2017-10-08
    • 2021-03-14
    相关资源
    最近更新 更多