Директивы модульного тестирования в Angular без TestBed & Component - PullRequest
0 голосов
/ 23 января 2020

Я написал Unit Testing для директивы, и она работает, но я хотел спросить, могу ли я протестировать ее без компонента и TestBed. Что я могу изменить здесь или что я могу улучшить? В чем идея создания TestComponent и идея TestBed

Вот код директивы.

@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;
  }
}

А вот код модульного тестирования

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

1 Ответ

1 голос
/ 23 января 2020

Согласно angular документам правильный способ тестирования Directive - это использовать какой-то компонент (TestComponent или нет).
Ответы на ваши вопросы:

  1. Вы можете протестировать вашу директиву, просто создав экземпляр, пока у него нет зависимостей DI.

const dir = new EndOfSeasonValidationDirective();
... some changes with inputs
expect(dir.validate()).toEqual({isInvalid: true})

Но лучший способ проверить его в более реальной среде - использовать в пара с некоторым компонентом. Поэтому идея создания TestComponent состоит в том, чтобы предоставить более реальную среду (запустить все внутренние механизмы angular под капотом) для вашего модульного теста.

  1. TestBed - вспомогательный инструмент для решения angular DI-зависимости и создание модуля тестирования.
  2. Я думаю, что ваш тест хорош, но вы можете улучшить его, покрыв его до 100%. Все случаи и If заявления должны быть проверены.

UPD В целом вы должны охватить следующие случаи:

  1. не следует проверять, если endOfSeason не предоставляется

  2. не должно проверяться, если startOfSeason не предоставляется

  3. не должно проверяться, если beginDate не предоставлено

  4. должно проверяться, если startOfSeason и endOfSeason равны

  5. должно проверяться, если (я не знаю, что означает это выражение в деловых словах) endOfSeason + (endOfSeason

После написания этих тестов ваше покрытие будет 100% для этой директивы, все случаи будут проверены. Вы можете запустить его, например, в Webstorm или Intellij IDEA, нажав кнопку Run with Coverage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...