[角度] [单元测试] this.isDateInstance不是一个函数

时间:2018-07-10 11:39:55

标签: angular angular-material angular5

我刚刚开始在我的应用程序上编写一些单元测试。这也是我的第一个测试。我从没写过。

我有一个带有某些字段的表单和一个使用角材料的带有日期选择器的字段。

但是我有这个错误TypeError: this.isDateInstance is not a function

I use 
Angular : 5.2.11
Material-Angular : 5.2.5

我有这个测试:

describe('Component : FormFillInfoPatientComponent', () => {
  let element;
  let de;
  let component: FormFillInfoPatientComponent;
  let fixture: ComponentFixture<FormFillInfoPatientComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MatMomentDateModule,
        HttpClientModule,
        FormsModule,
        ReactiveFormsModule,
        MatFormFieldModule,
        MatSelectModule,
        MatDatepickerModule,
        MatIconModule,
        // MatNativeDateModule,
        TranslateModule.forRoot({
          loader: {provide: TranslateLoader, useClass: TranslateFakeLoader}
        })
      ],
      declarations: [
        FormFillInfoPatientComponent,
        ControlMessagesComponent,
        DisplayInputDateLocalePipe,
      ],
      providers: [
        FormValidationService,
        DateAdapter,
        // NativeDateAdapter,
        MomentDateAdapter,
        FormBuilder,
        HttpClient,
        {
          provide: TranslateLoader,
          useFactory: function (http: HttpClient) {
            return new TranslateHttpLoader(http);
          },
          deps: [HttpClient]
        }]
    })
      .compileComponents();
  }));

  beforeEach(inject([DateAdapter], (dateAdapter: DateAdapter<any>) => {
    fixture = TestBed.createComponent(FormFillInfoPatientComponent);
    component = fixture.componentInstance;
    component.patientAccount = new PatientAccount();
    fixture.detectChanges();
    element = fixture.nativeElement;      // to access DOM element
    de = fixture.debugElement;
    dateAdapter.setLocale('fr');
  }));

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

  it('form invalid when empty', () => {
    expect(component.patientForm.valid).toBeFalsy();
  });

  it('should disabled button next', () => {
    let btnNext = element.getElementsByClassName('btn-next');
    expect(btnNext.disabled).toEqual(true);
  });

  it('should disabled button next', () => {

    const fields = component.fields;
    fields.forEach((field: { name: string, validators: Validators[] }) => {
      let currentDomField = component.patientForm.controls[field.name];
      expect(currentDomField.valid).toBeFalsy();
      field.validators.forEach((validator: Validators) => {
        let errors = currentDomField.errors || {};
        if (validator instanceof Validators.required) {
          expect(errors['required']).toBeTruthy();
        } else if (validator instanceof Validators.email) {
          currentDomField.setValue('test');
          expect(errors['pattern']).toBeTruthy();
        }
      });

    });

  });
});

我的组件

@Component({
  selector: 'dgk-form-fill-info-patient',
  templateUrl: './form-fill-info-patient.component.html',
  styleUrls: ['./form-fill-info-patient.component.scss'],
})
export class FormFillInfoPatientComponent implements OnInit, OnChanges {

  //....

  patientForm: FormGroup;

  fields = [
    {name: 'email', validators: [Validators.required, Validators.email]},
    {name: 'firstName', validators: [Validators.required]},
    {name: 'lastName', validators: [Validators.required]},
    {name: 'maidenName', validators: []},
    {name: 'phone', validators: []},
    {name: 'gender', validators: [Validators.required]},
    {name: 'dateOfBirth', validators: [Validators.required]},
  ];

  constructor(
    private readonly _formBuilder: FormBuilder,
    // private readonly _monitor: MonitoringService,
  ) {
    const formFields = this.fields.reduce((obj, field) => {
      let ret = ['', field.validators];
      obj[field.name] = ret;
      return obj;
    }, {});

    this.patientForm = this._formBuilder.group(formFields);
  }

  ngOnInit(): void {
    this.dateNow = moment();
  }

  // ....
}
<div fxLayout="column" fxFill="" fxFlex="">
  <form fxLayout="column" [formGroup]="patientForm">
    <mat-form-field>
      <input matInput placeholder="{{'GENERIC.FORM.EMAIL' | translate}}"
             type="email"
             [(ngModel)]="patientAccount.email"
             name="email"
             formControlName="email"
             required>
      <mat-error>
        <dgk-control-messages [control]="patientForm.controls.email"></dgk-control-messages>
      </mat-error>
    </mat-form-field>

    //.....
    <mat-form-field>
      <input matInput
             [matDatepicker]="myDatepicker"
             (focus)="myDatepicker.open()"
             [(ngModel)]="patientAccount.dateOfBirth"
             formControlName="dateOfBirth"
             [max]="dateNow"
             placeholder="{{'GENERIC.FORM.DOB' | translate}} (ex: {{ '1999-12-31T00:00:00' | displayInputDateLocale }})">
      <mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
      <mat-datepicker #myDatepicker></mat-datepicker>
      <mat-error>
        <dgk-control-messages [control]="patientForm.controls.dateOfBirth"></dgk-control-messages>
      </mat-error>
    </mat-form-field>


    <div fxLayout="row" fxLayoutAlign="end center" class="mat-padding">
      <button mat-raised-button color="accent" matStepperPrevious class="margin btn-previous">
        <mat-icon>arrow_back</mat-icon>
        {{'GENERIC.BUTTONS.BACK' |translate}}
      </button>
      <button mat-raised-button color="primary" matStepperNext class="margin btn-next" [disabled]="!patientForm.valid">
        {{'GENERIC.BUTTONS.NEXT' |translate}}
        <mat-icon>arrow_forward</mat-icon>
      </button>
    </div>

  </form>

</div>

我认为我已经导入了所有必需的模块或提供程序,但是我不知道为什么会发生此错误。

TypeError: this.isDateInstance is not a function
at DateAdapter.deserialize (webpack:////myPath/node_modules/@angular/material/esm5/core.es5.js?:689:35)
at MatDatepickerInput.set [as max] (webpack:////myPath/node_modules/@angular/material/esm5/datepicker.es5.js?:2370:68)
                                      at updateProp (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:12876:37)
at checkAndUpdateDirectiveInline (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:12587:19)
at checkAndUpdateNodeInline (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:14150:20)
at checkAndUpdateNode (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:14093:16)
at debugCheckAndUpdateNode (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:14986:76)
at debugCheckDirectivesFn (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:14927:13)
at Object.eval [as updateDirectives] (ng:///DynamicTestModule/FormFillInfoPatientComponent.ngfactory.js:573:5)
                                        at Object.debugUpdateDirectives [as updateDirectives] (webpack:////myPath/node_modules/@angular/core/esm5/core.js?:14912:21)

你有什么主意吗?还是同样的问题?

Thx

1 个答案:

答案 0 :(得分:0)

我遇到了同样的错误:TypeError: this.isDateInstance is not a function

在我的情况下,问题出在saturnDatePicker。

我已经导入了两个DateAdapter:

import {DateAdapter as DateAdapterT,} from 'saturn-datepicker'; 
import {DateAdapter} from '@angular/material/core';

提供者:

  providers: [
    ...providers,
    //DateAdapterT, //revmove this one and it works
    DateAdapter,
    ConfigsService

  ],

双重提供者同时也是一个问题。 感谢@Maryannah的提示:)