karma-jasmine - Karma + Ionic 4-无值访问器,用于带有名称的表单控制

标签 karma-jasmine ionic4 karma-webpack

我想知道如何使用 karma 实现单元形式测试。
我已经执行了一个测试,但是它始终会出现以下错误:Error: No value accessor for form control with name: 'email'
signup.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { IonicModule } from '@ionic/angular';
import { SignupPage } from './signup.page';

const routes: Routes = [{ path: '', component: SignupPage  }];

@NgModule({
  imports: [CommonModule, FormsModule, ReactiveFormsModule, IonicModule, RouterModule.forChild(routes)],
  declarations: [SignupPage]
})
export class SignupPageModule {}

signup.page.html
<ion-header no-border>
  <ion-toolbar>

    <ion-buttons slot="start">
      <ion-back-button defaultHref="/"></ion-back-button>
    </ion-buttons>

    <ion-title>
      <img src="../../../../assets/logo-colored.png">
    </ion-title>

    <ion-buttons slot="end">
      <div class="center-title-helper"></div>
    </ion-buttons>

  </ion-toolbar>
</ion-header>

<ion-content padding>

  <ion-progress-bar [hidden]="true" type="indeterminate"></ion-progress-bar>

  <img src="../../../../assets/logo-colored.png">

  <h3 text-center>Criar Conta</h3>

  <ion-list no-padding>
    <form [formGroup]="signupForm" (ngSubmit)="submitSignupForm()">

      <ion-item [ngClass]="{ 'ion-touched ion-invalid' : emailControl.invalid }">
        <ion-label position="floating">E-mail</ion-label>
        <ion-input formControlName="email" type="e-mail"></ion-input>
      </ion-item>

      <div *ngIf="emailControl.invalid" padding-start>
        <ion-note *ngIf="emailControl.hasError('required')" color="danger">
          Insira o seu endereço de e-mail
        </ion-note>
      </div>

      <ion-item [ngClass]="{ 'ion-touched ion-invalid' : passwordControl.invalid }">
        <ion-label position="floating">Senha</ion-label>
        <ion-input clearOnEdit="false" formControlName="password" type="password"></ion-input>
      </ion-item>

      <div *ngIf="passwordControl.invalid" padding-start>
        <ion-note *ngIf="passwordControl.hasError('required')" color="danger">
          Insira a sua senha
        </ion-note>
      </div>

      <ion-button [hidden]="true">Fake Button</ion-button>

    </form>
  </ion-list>

</ion-content>

<ion-footer>
  <ion-toolbar>
    <ion-button expand="block" shape="round" (click)="submitSignupForm()">Criar Conta</ion-button>
  </ion-toolbar>
</ion-footer>


signup.page.ts
import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-signup',
  templateUrl: './signup.page.html',
  styleUrls: ['./signup.page.scss'],
})
export class SignupPage implements OnInit {

  signupForm: FormGroup;

  constructor() { }

  ngOnInit() {
    this.signupForm = new FormGroup({
      email: new FormControl(''),
      password: new FormControl(''),
    });
  }

  submitSignupForm() {
    if (this.validateForm) {

    }
  }

  get validateForm(): boolean {
    if (this.emailControl.value === '') { this.emailControl.setErrors({ required: true }); }
    if (this.passwordControl.value === '') { this.passwordControl.setErrors({ required: true }); }

    return this.signupForm.valid;
  }

  get emailControl(): AbstractControl {
    return this.signupForm.controls['email'];
  }

  get passwordControl(): AbstractControl {
    return this.signupForm.controls['password'];
  }

}


signup.page.spec.ts
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { SignupPage } from './signup.page';

describe('SignupPage', () => {
  let component: SignupPage;
  let fixture: ComponentFixture<SignupPage>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SignupPage ],
      imports: [
        FormsModule,
        ReactiveFormsModule
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SignupPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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


运行ng test命令时的完整日志
Error: No value accessor for form control with name: 'email'
    at _throwError (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/forms/fesm5/forms.js:2144:1)
    at setUpControl (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/forms/fesm5/forms.js:2054:1)
    at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addControl (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/forms/fesm5/forms.js:5281:1)
    at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName._setUpControl (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/forms/fesm5/forms.js:5882:1)
    at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName.ngOnChanges (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/forms/fesm5/forms.js:5803:1)
    at checkAndUpdateDirectiveInline (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm5/core.js:22085:1)
    at checkAndUpdateNodeInline (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm5/core.js:23353:1)
    at checkAndUpdateNode (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm5/core.js:23315:1)
    at debugCheckAndUpdateNode (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm5/core.js:23949:1)
    at debugCheckDirectivesFn (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm5/core.js:23909:1)

最佳答案

我可以通过导入IonicModuleRouterTestingModule来解决此问题。

测试课是这样的。

signup.page.spec.ts

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { IonicModule } from '@ionic/angular';

import { SignupPage } from './signup.page';

describe('SignupPage', () => {
  let component: SignupPage;
  let fixture: ComponentFixture<SignupPage>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SignupPage ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      imports: [
        ReactiveFormsModule,
        RouterTestingModule,
        IonicModule
      ],
      providers: [FormBuilder],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SignupPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

});

关于karma-jasmine - Karma + Ionic 4-无值访问器,用于带有名称的表单控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54867973/

相关文章:

javascript - Jasmine 和 Backbone karma 的麻烦

angularjs - karma-webpack 没有加载 AngularJS 包

karma-jasmine - 无法加载记者 "coverage-istanbul"

angular - 在 ionic 路由器导出中时, ion-content 与 ionic 接头重叠

cordova - 使用相机和文件插件在 Ionic 4 中上传图片

angular - ionic 4 : Issue Running Livereload with Environment Configuration Options

angularjs - 如何从 webpack 中包含 vendor 包以用于 karma 测试运行器

unit-testing - 错误 : Expected one matching request for criteria "Match by function: ", 未找到

javascript - 在嵌套 promise 之后使用 tick() 不会导致等待 promise 完成(Karma/Jasmine)

typescript - Jasmine Spec Helpers 未加载