How to test a component which contains a custom form control?

荒凉一梦 提交于 2020-01-04 03:01:07

问题


I got a component like this

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

As you see it's a custom form control. I use it in a component which I'm going to test.

    @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 {...}

So how can I mock app-custom-form-control for my test?

The current implementation needs a real component...

  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();
  }));

Otherwise(without declaration the component) I got an error Failed: No value accessor for form control with name: app-custom-form-control


回答1:


When doing tests to Angular applications, there are two main approaches (and a mix) you can follow:

1- Stubbing unneeded components, where

(...) you create and declare stub versions of the components and directive that play little or no role in the tests (...)

2- The NO_ERRORS_SCHEMA which

(...) tells the Angular compiler to ignore unrecognized elements and attributes (...)

With this last one the compiler won't throw an error when it encounters the app-custom-form-control selector in the AppComponent template.

3- Use both techniques together

Selecting one approach or another, it's up to you, since it depends on the final goal you aim to with the test.


Applying approach 1 it would be something like this:

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();
  }));
//...
});


来源:https://stackoverflow.com/questions/50821486/how-to-test-a-component-which-contains-a-custom-form-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!