Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 8 Unit Test, Cannot set property 'valueAccessor' of null

I'm trying to simply pass the test (should create - component=> toBeTruthy) for the custom component (angular component class) implemented with ControlValueAccessor. I've injected NgControl in constructor and pass the this keyword.

 constructor(@Optional() @Self() public controlDir?: NgControl) {
    this.controlDir.valueAccessor = this;
  } 

And then on ngOnInit()

ngOnInit() {
    const control = this.controlDir.control;
    const validators = control.validator ? [control.validator] : [];
    const asyncValidators = control.asyncValidator ? [control.asyncValidator] : [];

    control.setValidators(validators);
    control.setAsyncValidators(asyncValidators);
    control.updateValueAndValidity();
  }

In the test file

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

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

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

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

});

And the errors

TypeError: Cannot set property 'valueAccessor' of null

I'd be appreciated if anyone shares your ideas to solve this issue?

Thank you. Rabin

like image 873
Rabin Rai Avatar asked Nov 22 '25 14:11

Rabin Rai


1 Answers

I got solved this issue by creating the new mock class component with calling the <app-text-input formControlName="test"></app-text-input> template including form.

Here is a code details:

@Component({
  template: `
  <form [formGroup]="form">
   <app-text-input formControlName="input">
   </app-text-input>
  </form>`
})
class TestingInput {
  @ViewChild(TextInputComponent, { static: true })
  textInputComponent: TextInputComponent;

  form = new FormGroup({
    input: new FormControl('Test Value')
  });
}

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [TextInputComponent, TestingInput],
      imports: [ReactiveFormsModule]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(TestingInput);
    component = fixture.componentInstance.textInputComponent;
  });

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

Thanks, Everyone for the answer and comments, all did not solve the exact issue though at least got the idea to figure out. Feel free to post the answer if you have any other better way to solve this issue. Much appreciated!

like image 158
Rabin Rai Avatar answered Nov 24 '25 04:11

Rabin Rai



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!