如何测试包含自定义表单控件的组件?

时间:2018-06-12 16:04:31

标签: angular unit-testing testing custom-controls angular-reactive-forms

我有一个像这样的组件

@Component({
      selector: 'app-custom-form-control',
      templateUrl: '<input>',
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => SelectComponent),
          multi: true
        }
      ]
    })
export class CustomFormControlComponent implements ControlValueAccessor {...}

如您所见,它是一个自定义表单控件。我在一个我要测试的组件中使用它。

    @Component({
      selector: 'app-root',
      templateUrl: '<div [formGroup]="form">
          <app-custom-form-control formControlName="my_field"></app-custom-form-control>
      </div>',
    })
    export class AppComponent implements OnInit, OnDestroy {...}

那么我如何模拟app-custom-form-control进行测试呢?

当前的实施需要一个真实的组件......

  beforeEach(async(() => {
    const testRouter = new RouterStub();
    const testDataService = new DataServiceStub();
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        CustomFormControlComponent // it is a real stuff
      ],
      imports: [
        ReactiveFormsModule
      ],
      providers: [
        { provide: Router, useValue: testRouter },
        { provide: DataService, useValue: testDataService }
      ],
      schemas: [ NO_ERRORS_SCHEMA ]
    }).compileComponents();
  }));

否则(没有声明组件)我收到错误Failed: No value accessor for form control with name: app-custom-form-control

1 个答案:

答案 0 :(得分:2)

在对Angular应用程序进行测试时,您可以遵循两种主要方法(和mix ):

1- Stubbing unneeded components,其中

  

(...)您创建并声明组件的存根版本   在测试中扮演很少或没有角色的指令(...)

2- NO_ERRORS_SCHEMA

  

(...)告诉Angular编译器忽略无法识别的元素和属性(...)

使用最后一个编译器,遇到app-custom-form-control模板中的AppComponent选择器时,编译器不会抛出错误。

3- Use both techniques together

选择一种或另一种方法,这取决于您,因为它取决于您在测试中的最终目标。

应用方法1将是这样的:

describe('AppComponent', () => {

// component stub
@Component({selector: 'app-custom-form-control', template: ''})
class CustomFormControlComponentStub {}
//...
  beforeEach(async(() => {
    const testRouter = new RouterStub();
    const testDataService = new DataServiceStub();
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        CustomFormControlComponentStub // it is fake! stuff
      ],
      // ... code omitted
    }).compileComponents();
  }));
//...
});