I successfully implemented Unit Testing for a directive and it is working fine. However, I am curious to know if there is a way to test it without using a component and TestBed. How can I make improvements in my current setup? Also, what is the concept behind creating a TestComponent and using TestBed?
Below is the code snippet of the directive:
@Directive({
selector: '[ngModel][endOfSeasonValidation]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => EndOfSeasonValidationDirective),
multi: true,
},
],
})
export class EndOfSeasonValidationDirective extends AbstractValidatorDirective {
@Input('beginDate')
public beginDate: Date | null;
@Input('startOfSeason')
public startOfSeason: number | null;
public validate(control: AbstractControl): ValidationErrors | null {
const endOfSeason = control.value;
if (!endOfSeason || !this.startOfSeason || !this.beginDate) {
return null;
}
if (
endOfSeason === this.startOfSeason ||
endOfSeason + (endOfSeason < this.startOfSeason ? 12 : 0) - this.startOfSeason === 11
) {
return { isInvalid: true };
}
return null;
}
}
And here is how the unit testing code looks like:
@Component({
template: `
<form>
<select
endOfSeasonValidation
[ngModel]="endOfSeason"
name="endOfSeason"
[beginDate]="beginDate"
[startOfSeason]="startOfSeason"
></select>
</form>
`,
})
class EndOfSeasonValidationTestComponent {
public beginDate = new Date('2020-01-16');
public startOfSeason: number | null;
public endOfSeason: number | null;
@ViewChild(NgForm, { static: true })
public form: NgForm;
}
describe('EndOfSeasonValidationDirective', () => {
let fixture: ComponentFixture<EndOfSeasonValidationTestComponent>;
let form: NgForm;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
EndOfSeasonValidationTestComponent,
EndOfSeasonValidationDirective,
DateAccessorPluginDirective,
SelectAccessorDirective,
],
imports: [FormsModule],
}).compileComponents();
fixture = TestBed.createComponent(EndOfSeasonValidationTestComponent);
fixture.detectChanges();
await fixture.whenStable();
form = fixture.componentInstance.form;
});
it('should not validate if beginDate or startOfSeason or endOfSeason are not given', async () => {
fixture.componentInstance.beginDate = new Date('2020-01-01');
fixture.detectChanges();
await fixture.whenStable();
expect(form.valid).toBeTruthy();
expect(form.errors).toBeFalsy();
});
it('should validate if startOfSeason and endOfSeason are equal', async () => {
fixture.componentInstance.beginDate = new Date('2020-12-02');
fixture.componentInstance.startOfSeason = 2;
fixture.componentInstance.endOfSeason = 2;
fixture.detectChanges();
await fixture.whenStable();
expect(fixture.componentInstance.form.invalid).toBeTruthy();
});
});