I have a simple custom control as below. Everything is working but the unit test is failing. How can I unit test this custom control? How can I pass a valid NgControl directive?
I have tried using providers:
[
  {
    provide: NgControl,
    useValue: new FormGroup()
  }
]
but I still get the same error.
core-edi.component.ts
import { Component, OnInit, Input, ViewChild, ElementRef, Self, Optional, forwardRef } from '@angular/core';
import {
  ControlValueAccessor, NG_VALUE_ACCESSOR, Validator, AbstractControl,
  ValidatorFn, Validators, NG_VALIDATORS, NgControl, NgForm
} from '@angular/forms';
import { Placeholder } from '@angular/compiler/src/i18n/i18n_ast';
@Component({
  selector: 'app-core-edi',
  templateUrl: './core-edi.component.html',
  styleUrls: ['./core-edi.component.css'],
})
export class CoreEdiComponent implements ControlValueAccessor, Validator, OnInit {
  @ViewChild('input') input: ElementRef;
  disabled;
  @Input() type = 'text';
  @Input() isRequired: boolean = false;
  @Input() pattern: string = null;
  @Input() label: string = null;
  @Input() placeholder: string;
  @Input() errorMsg: string;
  @Input() min: number;
  @Input() minLength: number;
  myhint: string = '10 digit number';
  constructor(@Self() public controlDir: NgControl) {
    this.controlDir.valueAccessor = this;
  }
  ngOnInit() {
    const control = this.controlDir.control;
    const validators: ValidatorFn[] = control.validator ? [control.validator] : [];
    if (this.isRequired) {
      validators.push(Validators.required);
    }
    if (this.pattern) {
      validators.push(Validators.pattern(this.pattern));
    }
    if (this.min) {
      validators.push(Validators.min(this.min));
    }
    control.setValidators(validators);
    control.updateValueAndValidity();
    this.placeholder = this.placeholder + (this.isRequired ? '*' : '');
  }
  onChange(event) { 
  }
  onTouched() {
   }
  writeValue(obj: any): void {
    this.input.nativeElement.value = obj;
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }
  validate(c: AbstractControl): { [key: string]: any; } {
    const validators: ValidatorFn[] = [];
    if (this.isRequired) {
      validators.push(Validators.required);
    }
    if (this.pattern) {
      validators.push(Validators.pattern(this.pattern));
    }
    if (this.min) {
      validators.push(Validators.min(this.min));
    }
    return validators;
  }
core-edi.component.html
<div class="form-label-group" fxLayout="column" fxLayoutGap="5px">
  <mat-form-field class="edi-field-width">   
        <input matInput class="form-control" 
            [type]="type" #input
            (input)="onChange($event.target.value)"
            (blur)="onTouched()"
            [disabled]="disabled"
            [placeholder]="placeholder"
            [min]="1111111111"
            [minLength] = 10
            (keyup)="mykeyup()">
            <mat-hint>Hint: {{ myhint }}</mat-hint>
 </mat-form-field>
 <span class="error"
     *ngIf="controlDir && !controlDir.control.valid 
     && controlDir.control.touched">{{errorMsg}}</span>
</div>
core-edi.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CoreEdiComponent } from './core-edi.component';
import { FormsModule, ReactiveFormsModule, FormControl, NgControl, FormControlDirective } from '@angular/forms';
import { MaterialModule } from 'src/app/material/material.module';
fdescribe('CoreEdiComponent', () => {
  let component: CoreEdiComponent;
  let fixture: ComponentFixture<CoreEdiComponent>;
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ CoreEdiComponent ],
      imports: [
        FormsModule,
        ReactiveFormsModule,
        MaterialModule
      ]
    })
    .compileComponents();
  }));
  beforeEach(() => {
    fixture = TestBed.createComponent(CoreEdiComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
 it('should create', () => {
    expect(component).toBeTruthy();
  });
});
No provider for NgControl ("[ERROR ->]<app-core-edi></app-core-edi>"): @0:0
            at syntaxError (./node_modules/@angular/compiler/fesm5/compiler.js?:1275:17)
            at TemplateParser.parse (./node_modules/@angular/compiler/fesm5/compiler.js?:15084:19)
            at JitCompiler._parseTemplate (./node_modules/@angular/compiler/fesm5/compiler.js?:24272:37)
            at JitCompiler._compileTemplate (./node_modules/@angular/compiler/fesm5/compiler.js?:24259:23)
            at eval (./node_modules/@angular/compiler/fesm5/compiler.js?:24202:62)
            at Set.forEach (<anonymous>)
            at JitCompiler._compileComponents (./node_modules/@angular/compiler/fesm5/compiler.js?:24202:19)
            at eval (./node_modules/@angular/compiler/fesm5/compiler.js?:24120:19)
            at Object.then (./node_modules/@angular/compiler/fesm5/compiler.js?:1266:77)
            at JitCompiler._compileModuleAndAllComponents (./node_modules/@angular/compiler/fesm5/compiler.js?:24118:26)
        Expected undefined to be truthy.
            at UserContext.eval (./src/app/core/core-edi/core-edi.component.spec.ts?:30:27)
            at ZoneDelegate.invoke (./node_modules/zone.js/dist/zone.js?:390:26)
            at ProxyZoneSpec.onInvoke (./node_modules/zone.js/dist/zone-testing.js?:288:39)
 
     
    