FormGroup没有在我的测试

时间:2018-04-11 08:28:03

标签: angular jest angular-reactive-forms controlvalueaccessor

我有一个presentational / dumb组件,它使用输入来使用formBuilder填充HTML模板。这一切都很好但是当我开始测试时,事情并不像它们应该的那样顺利。

我想测试一些文本框正在使用我的输入值正确填充。我希望formGroup在I:

之后更新我的HTML
  1. 设置输入
  2. 呼叫检测更改
  3. 致电ngOnInit
  4. 在我的测试中,我使用默认行为覆盖了OnPush检测策略。

    最终我的目标是使用Jest对这些组件进行快照测试,因为它使得比较属性变得更加容易,但为此,我首先需要能够正确地呈现我的HTML。

    我正在使用Jest运行测试,我相信它使用JsDOM。

    @Component({
      selector: 'network',
      templateUrl: './network.component.html',
      styleUrls: ['./network.component.scss'],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class NetworkComponent implements OnInit {
      @Input() network: Network;
    
      public formGroup: FormGroup;
    
    
      constructor(private formBuilder: FormBuilder) {}
    
      ngOnInit() {
        this.formGroup = this.formBuilder.group({
          details: [this.network || null],
        });
      }
    }
    <div class="container-fluid">
      <form [formGroup]="formGroup" novalidate (ngSubmit)="submit()">
        <div class="row">
          <div class="col-4">
            <h2>Details</h2>
            <app-network-details formControlName="details"></app-network-details>
          </div>  
        </div>    
        <div class="row">
          <button class="btn btn-primary" type="submit">{{submitButtonText}}</button>
        </div>
      </form>
    </div>

    我的app-network-details组件如下所示:

    @Component({
      selector: 'app-network-details',
      templateUrl: './network-details.component.html',
      styleUrls: ['./network-details.component.scss'],
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => NetworkDetailsComponent),
          multi: true
        }
      ],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class NetworkDetailsComponent implements OnInit, ControlValueAccessor, OnChanges {
      public details = {};
      @Output() change = new EventEmitter<number>();
    
      propagateChange = (_: any) => {};
    
      ngOnChanges(changes: SimpleChanges): void {
        this.propagateChange(this.details);
      }
      writeValue(obj: any): void {
        if (obj) {
          this.details = obj;
        }
      }
      registerOnChange(fn: any): void {
        this.propagateChange = fn;
      }
      registerOnTouched(fn: any): void {}
    
      setDisabledState?(isDisabled: boolean): void {
        // throw new Error('Method not implemented.');
      }
    
      public onChange(e: any) {
        this.details[e.target.name] = e.target.value;
        this.propagateChange(this.details);
      }
      constructor() {
        this.details = {};
      }
    
      ngOnInit() {}
    }
    <div class="form-group">
      <input class="form-control" type="text" placeholder="Name" name="name" (change)="onChange($event)" [value]="details.name || null"
      />
    </div>
    <div class="form-group">
      <input class="form-control" type="text" placeholder="Description" name="description" (change)="onChange($event)" [value]="details.description || null"
      />
    </div>
    <div class="form-group">
      <input class="form-control" type="text" placeholder="Local Code" name="localCode" (change)="onChange($event)" [value]="details.localCode || null"
      />
    </div>

    这是我的测试设置:

    describe('NetworkComponent', () => {
      let component: NetworkComponent;
      let fixture: ComponentFixture<NetworkComponent>;
      const compilerConfig = { preserveWhitespaces: false } as any;
    
      beforeEach(
        async(() => {
          TestBed.configureCompiler(compilerConfig)
            .configureTestingModule({
              declarations: [
                NetworkComponent,
                NetworkDetailsComponent,
                NetworkAuthorisationComponent,
                MailboxListStubComponent,
                AddMailboxStubComponent,
                UpdateMailboxStubComponent,
                DropdownStubComponent
              ],
              imports: [ReactiveFormsModule],
              providers: [{ provide: ComponentFixtureAutoDetect, useValue: true }]
            })
            .overrideComponent(NetworkComponent, {
              set: {
                changeDetection: ChangeDetectionStrategy.Default
              }
            })
            .compileComponents();
        })
      );
    
      beforeEach(() => {
        fixture = TestBed.createComponent(NetworkComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it('should intialize inputs with values from network', () => {
        const network: Network = {
          id: 1,
          name: 'a',
          description: 'b',
          localCode: 'c',
          authorisation: 'd',
          company: 'e',
          networkType: 'oftp'
        };
        component.network = network;
        fixture.detectChanges();
        component.ngOnInit();
    
        const inputElement = fixture.nativeElement.querySelector('input[name="description"]');
    
        inputElement.dispatchEvent(new Event('change'));
        fixture.detectChanges();
    
        expect(inputElement.value).toEqual('b');
      });
    });

    修改 我设法隔离了这个问题。由于我的NetworkDetailsComponent,我的测试失败了。我可能没有正确实现ControlValueAccessor接口。如果我在一个具有formControlName指令的输入元素上重写我的测试和断言,它就可以工作。

0 个答案:

没有答案