角单元测试-反应式表格值未更新 [英] Angular Unit testing - Reactive Form value not updating

查看:53
本文介绍了角单元测试-反应式表格值未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是角单元测试的新手. 测试方案:html中的表单视图值等于组件表单值. 电子邮件值是通过共享值检索的,并在组件注册表单中使用.我可以使用反应形式从组件中检索电子邮件值,但是当尝试通过本机元素进行访问时,它为空. 下面是component.ts

I am new to angular unit testing. Test Scenario: The form view value in the html is equal to the component form value. The email value is retrieved by a shared value and being used in the component registration form. I could retrieve the email value from the component using the reactive forms, but when trying to access via the native element, it gives empty. Below is the component.ts

ngOnit(public serviceEmail) {
    this.assignEmailAvailable();
    this.createRegistration();

    }
assignEmailAvailable() {
 if(service.email){
    this.email = serviceEmail.email;
  }
 }   
createRegistration() {
   this.registerForm = new FormGroup({
       email:new FormControl({value:this.email})
    })
}

在component.spec.ts中,我将调用此函数并检查两个值是否相同. component.spec.ts

In the component.spec.ts, I am gonna call this function and check whether both values are same. component.spec.ts

 beforeEach(() => {
    fixture = TestBed.createComponent(RegisterComponent);
    component = fixture.componentInstance;
    service = TestBed.get(serviceEmail);
  });
it('Registration Form Creation', fakeAsync(() => {
    service.email = "dsf@gmail.com";

    fixture.detectChanges();

    component.assignEmailAvailable();
    component.createRegisterForm();

    fixture.detectChanges();
    fixture.whenStable().then(() => {
    const email = fixture.debugElement.query(By.css('input[id="email"]')).nativeElement;
//The value is empty even after creating the form using the component function
    expect(email.value).toBe(component.emailValue);
    });
//THis returns me the value set
    expect(component.registerForm.get('email').value).toBe(component.emailValue);
  }));

推荐答案

我花了大约2个小时来解决这个问题.根据我的经验,在beforeEach()函数中有一些需要解决的问题.首先,您需要将ReactiveFormsModule导入到TestBed中,以便更改检测可以正确执行所有操作.其次,您需要在beforeEach()调用中手动运行ngOnInit()和Fixture.detectChanges()来设置表单.请参阅下面的我的beforeEach()函数.我还包括了我的其余代码,其他有此问题的人可能会发现它们与之相关.

I just spent like 2 hours trying to figure out this problem. From my experience, you have a few problems in your beforeEach() function that you need to resolve. First, you need to import the ReactiveFormsModule into your TestBed so that Change Detection does everything correctly. Second, you need to manually run ngOnInit() and fixture.detectChanges() in your beforeEach() call to set up your form. See my beforeEach() functions below. I've also included the rest of my code that others with this problem may find relevant.

组件模板:


    <form [formGroup]='emailForm' (ngSubmit)='handleSubmit()'>
      <div class='form-group'>
        <label for='email'>Email address</label>
        <input type='email' class='form-control' id='email' placeholder='Enter email'
          formControlName='email'>

组件TS:

      constructor(
        private apiService: ApiService,
        private fb: FormBuilder,
        private router: Router
      ) { }
    
      ngOnInit() {
        this.initializeForm();
      }
    
      initializeForm(): void {
        this.formSubmitted = false;
        this.serverProcessing = false;
        this.emailForm = this.fb.group({
          email: ['', Validators.compose([Validators.required, Validators.email])]
        });
      }
    
      get email() {return this.emailForm.get('email');}

在Spec TS中都是beforeEach()调用

Both beforeEach() calls in Spec TS:

      beforeEach(
        async(() => {
    
          apiServiceSpy = jasmine.createSpyObj('ApiService', ['sendResetPasswordEmail']);
          routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
    
          TestBed.configureTestingModule({
            declarations: [ SendPasswordResetEmailComponent ],
    
            // Need to import this if we're messing with Reactive Form inputs!!
            imports: [ReactiveFormsModule],
    
            providers: [
              {provide: ApiService, useValue: apiServiceSpy},
              {provide: Router, useValue: routerSpy},
              {provide: FormBuilder},
            ]
          })
          .compileComponents();
        })
      );
    
      beforeEach(() => {
        fixture = TestBed.createComponent(SendPasswordResetEmailComponent);
        component = fixture.componentInstance;
    
        // ngOnInit() doesn't get called automatically, so we have to do it ourselves
        component.ngOnInit();
    
        // Telling the fixture to detect changes is really important to correctly bind data
        // Do this after calling ngOnInit() so changes propagate to the template 
        fixture.detectChanges();
      });

样品测试规格:

      it('should have an error for no username', () => {
        const componentElement: HTMLElement = fixture.nativeElement;
        const emailInput: HTMLInputElement = componentElement.querySelector('input');
        emailInput.value = '@gmail.com';
        emailInput.dispatchEvent(new Event('input'));
        fixture.detectChanges();
        expect(component.email.errors.email).toBeTruthy('@gmail.com valid');
      });
    
      it('should have no error if the email is valid', () => {
        const componentElement: HTMLElement = fixture.nativeElement;
        const emailInput: HTMLInputElement = componentElement.querySelector('input');
        emailInput.value = 'joe@test.go';
        emailInput.dispatchEvent(new Event('input'));
        fixture.detectChanges();
        expect(component.email.errors).toBeFalsy('joe@test.go invalid');
      });

这篇关于角单元测试-反应式表格值未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆