【问题标题】:Testing submitted data from Angular Reactive form测试来自 Angular Reactive 表单的提交数据
【发布时间】:2020-07-31 04:45:53
【问题描述】:

基于https://angular.io/guide/reactive-forms 中的第一个示例,我创建了以下哑组件:

@Component({
  selector: 'app-name-editor',
  templateUrl: './name-editor.component.html',
  styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {

  name = new FormControl('');

  @Output('submitted') submitted = new EventEmitter<string>();

  onSubmit() { this.submitted.emit(this.name.value); }
}

... 我想为此编写一个单元测试来验证是否提交了一个值。这使用了 https://angular.io/guide/testing#component-inside-a-test-host 中建议的 TestHost :

@Component({
  template: `
     <app-name-editor (submitted)=onSubmit($event)>
     </app-name-editor>
   `})
class TestHostComponent {
  submitted: string;
  onSubmit(data: string) { this.submitted = data; }
}

describe('NameEditorComponent', () => {
  let testHost: TestHostComponent;
  let fixture: ComponentFixture<TestHostComponent>;
  let editorDebugElt: DebugElement;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ NameEditorComponent, TestHostComponent ]
    });
    fixture = TestBed.createComponent(TestHostComponent);
    testHost = fixture.componentInstance;
    editorDebugElt = fixture.debugElement.query(By.directive(NameEditorComponent));
    fixture.detectChanges();
  });

  it('should capture data', () => {
    const compiled = fixture.debugElement.nativeElement;
    const nameInput = compiled.querySelector('input[type="text"]');
    expect(nameInput).toBeTruthy();
    nameInput.value = 'This is a test';
    fixture.detectChanges();

    // Find submit button
    const submitInput = compiled.querySelector('input[type="submit"]');
    expect(submitInput).toBeTruthy();

    // Trigger click action
    expect(testHost.submitted).toBeFalsy();
    submitInput.click();

    // Submitted
    expect(testHost.submitted).toBe('This is a test');    
  });
});

测试失败,但我不明白为什么。输入中填充了测试结果下方所示的值。任何帮助将不胜感激。

【问题讨论】:

    标签: angular angular-reactive-forms angular9 angular-unit-test


    【解决方案1】:

    表单提交空值的原因是因为反应式表单是异步的。

    编辑表单并在之后立即提交将提交一个空白表单,因为编辑是异步进行的。现在通过添加 500 毫秒的等待时间来通过测试,但很高兴知道如何避免等待:

        // Wait for asynchronous update on reactive form to happen
        setTimeout(() => {
    
          // Trigger click action
          expect(testHost.submitted).toBeFalsy();
          submitInput.click();
    
          // Submitted
          expect(testHost.submitted).toBe('This is a test');
    
        }, 500);
    

    【讨论】:

      【解决方案2】:

      而不是使用“这是一个测试”来检查提交。可以窥探 testHost.submitted 中的 emit 方法,检查它是否被表单控件的值调用。

      it('should capture data', () => {
        const compiled = fixture.debugElement.nativeElement;
        spyOn(testHost.submitted, 'emit')
        testHost.name.value('This is a test')
        const submitInput = compiled.querySelector('input[type="submit"]');
        submitInput.click();
        expect(testHost.submitted.emit).toHaveBeenCalled();
        expect(testHost.submitted.emit).toHaveBeenCalledWith(testHost.name.value)
      });
      

      【讨论】:

      • 感谢以上内容,但我遇到的问题与提交检测无关。我现在发现发生了什么:1)在表单上设置了值,2)随后立即提交了表单。由于反应式表单是异步的,表单提交时输入为空白。
      猜你喜欢
      • 1970-01-01
      • 2018-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      • 2019-04-10
      • 2020-12-19
      • 1970-01-01
      相关资源
      最近更新 更多