I have a basic directive which acts on an input box to limit the lowest value allowed, in this test case nothing less than zero.
However, I can't get this test to pass because of the error inline template:0:0 caused by: null is not an object .
It seems to maybe be related to ngModel but none of my searches on the interwebs of the YouBooks or FaceTubes or Yahoogles yields an answer.
import { Directive, Input, ElementRef, HostListener } from '@angular/core';
import { NgModel } from '@angular/forms';
@Directive({
selector: '[dleGbMinValue]',
providers: [NgModel]
})
export class MinValueDirective {
@Input('dleGbMinValue') minValue : string;
constructor(private el: ElementRef, private model: NgModel) { }
@HostListener('change') onChange() {
if (this.el.nativeElement.value && parseFloat(this.el.nativeElement.value) < parseFloat(this.minValue)) {
this.model.valueAccessor.writeValue(parseFloat(this.minValue));
this.model.viewToModelUpdate(parseFloat(this.minValue));
}
}
@HostListener('blur') onBlur() {
if (!this.el.nativeElement.value || parseFloat(this.el.nativeElement.value) < parseFloat(this.minValue)) {
this.model.valueAccessor.writeValue(parseFloat(this.minValue));
this.model.viewToModelUpdate(parseFloat(this.minValue));
}
}
}
And here it the test code
import { MinValueDirective } from './min-value.directive';
@Component({
template: `<input type="number" dleGbMinValue="0">`
})
class TestMinValueDirectiveComponent {
}
describe('Directive: MinValueDirective', () => {
let component: TestMinValueDirectiveComponent;
let fixture: ComponentFixture<TestMinValueDirectiveComponent>;
let inputEl: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestMinValueDirectiveComponent, MinValueDirective]
});
fixture = TestBed.createComponent(TestMinValueDirectiveComponent);
component = fixture.componentInstance;
inputEl = fixture.debugElement.query(By.css('input'));
fixture.detectChanges();
});
it('should stop at min value on change', () => {
expect(inputEl.nativeElement.value).toEqual('');
inputEl.nativeElement.value = '-5';
inputEl.triggerEventHandler('change', null);
fixture.detectChanges();
expect(inputEl.nativeElement.value).toEqual(0);
});
});
You do not need to provide NgModel
in MinValueDirective
.
Use ngModel
directive from FormsModule
instead.
@Component({
template: `<input type="number" ngModel dleGbMinValue="0">` // add ngModel
})
class TestMinValueDirectiveComponent {}
Don't forget to import FormsModule
to your testing module:
TestBed.configureTestingModule({
imports: [FormsModule], // here
declarations: [TestMinValueDirectiveComponent, MinValueDirective]
});
Then to prevent error: inline template:0:0 caused by: Cannot read property 'target' of null
from NumberValueAccessor
change
inputEl.triggerEventHandler('change', null);
to
inputEl.triggerEventHandler('change', { target: { value: '-5'}});
A complete test you can find in Plunker Example