Angular 8 директива модульного теста, которая включает setTimeout - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть следующая простая директива автофокуса:

@Directive({
  selector: '[appAutoFocus]',
})
export class AutofocusDirective implements AfterContentInit {

  @Input() public appAutoFocus: boolean;

  public constructor(private el: ElementRef) { }

  public ngAfterContentInit() {
    if (this.appAutoFocus) {
      setTimeout(() => {
        this.el.nativeElement.focus();
      }, 300);
    }
  }
}

Я сейчас пытаюсь написать несколько простых модульных тестов, но 2 из 3 тестов не пройдены.

@Component({
  template: '<input type="text" [appAutoFocus]="true" />'
})
class TestComponent {
  constructor() { }
}

fdescribe('AutoFocusDirective', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;
  let inputEl: DebugElement;
     beforeEach(() => {
        TestBed.configureTestingModule({
          declarations: [
            TestComponent,
            AutofocusDirective
          ]
        });

        fixture = TestBed.createComponent(TestComponent);
        component = fixture.componentInstance;
        inputEl = fixture.debugElement.query(By.css('input'));

        spyOn(inputEl.nativeElement, 'focus');
        fixture.detectChanges();
      });

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

      it('should call the focus event', fakeAsync(() => {
        tick(400);
        fixture.detectChanges();
        fixture.whenStable().then(() => {
         expect(inputEl.nativeElement.focus).toHaveBeenCalled();
        });
      }));

      it('should autofocus the input control', () => {
        const debugEl: DebugElement = fixture.debugElement;
        expect(debugEl.query(By.css('input:focus'))).not.toBe(null);
      });

«Следует вызвать событие фокуса» завершается неудачей с Spec 'AutoFocusDirective should call the focus event' has no expectations.

«Если автофокусировка управления вводом» завершается с Expected null not to be null

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Единственный способ заставить это работать - добавить setTimeout к тесту spe c, так что теперь это выглядит так:

  it('should call the focus event', (done) => {
    fixture.detectChanges();
    setTimeout(() => {
      expect(inputEl.nativeElement.focus).toHaveBeenCalled();
      done();
    }, 500);
  });

Если честно, это мусорное решение, но я потратил слишком много времени на это.

0 голосов
/ 18 февраля 2020

Возможно, вы не можете соединить fakeAsync с fixture.whenStable.

Попробуйте:

      it('should call the focus event', fakeAsync(() => {
        tick(400);
        fixture.detectChanges();
        // You should check out `flush` method to resolve instead of specifying the time in the argument of tick
        expect(inputEl.nativeElement.focus).toHaveBeenCalled();
      }));

     it('should autofocus the input control', fakeAsync(() => {
        tick(400);
        fixture.detectChanges();
        const debugEl: DebugElement = fixture.debugElement;
        expect(debugEl.query(By.css('input:focus'))).not.toBe(null);
      }));

Оба ваших теста выполняют одно и то же, поэтому рассмотрите возможность объединения обоих в один it блок.

Хорошее чтение для вас: https://alligator.io/angular/testing-async-fakeasync/

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