Angular: тестирование директивы по настройке фокуса - PullRequest
0 голосов
/ 04 июня 2018

У меня проблема с выполнением того, что написано в названии ... вот моя директива:

import {Directive, Input, ElementRef, Renderer, OnInit, OnDestroy} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';

@Directive({
  selector: '[focusController]'
})
export class FocusControllerDirective implements OnInit, OnDestroy {
  @Input('doFocus') private readonly _doFocus$: Observable<any>;
  private readonly _destroy$ = new Subject();

  // TODO: check if Renderer3 supports setting focus after update. see also: https://github.com/angular/angular/issues/15674
  constructor(private hostEl: ElementRef, private renderer: Renderer) {}

  ngOnInit() {
    this._doFocus$.takeUntil(this._destroy$).subscribe(() => {
      this.renderer.invokeElementMethod(this.hostEl.nativeElement, 'focus', []);
    });
  }

  ngOnDestroy(): void {
    this._destroy$.next();
  }
}

, а вот файл спецификации:

/* tslint:disable:no-unused-variable */
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {Component, DebugElement} from '@angular/core';
import {By} from '@angular/platform-browser';
import {FocusControllerDirective} from '@lib/form-directives';
import {Subject} from 'rxjs/Subject';

@Component({
  template: `<input type="text" focusController [doFocus]="doFocus$">`
})
class ParentOfForceFocusComponent {
  doFocus$ = new Subject();
}

describe('FocusControllerDirective', () => {
  let component: ParentOfForceFocusComponent;
  let fixture: ComponentFixture<ParentOfForceFocusComponent>;
  let debugElement: DebugElement;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ParentOfForceFocusComponent, FocusControllerDirective]
    });
    fixture = TestBed.createComponent(ParentOfForceFocusComponent);
    component = fixture.componentInstance;
    debugElement = fixture.debugElement.query(By.css('input'));
    spyOn(debugElement.nativeElement, 'focus');
    fixture.detectChanges();
  });

  it('should trigger focus on Subject update', async(() => {
    let elementWithFocus = debugElement.query(By.css(':focus'));
    expect(elementWithFocus).toBeNull();
    component.doFocus$.next();
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      elementWithFocus = debugElement.query(By.css(':focus'));
      expect(elementWithFocus).not.toBeNull();
      expect(elementWithFocus).toBe(debugElement);
    });
  }));
});

Жасмин говорит мне Expected null not to be null. Понятия не имею, что делать, ошибок нет, ничего.Просто не пройден тест, несмотря на то, что код работает при тестировании вручную в браузере.

1 Ответ

0 голосов
/ 04 июня 2018

Вы не должны использовать By.css(':focus'), вместо этого попробуйте document.activeElement:

elementWithFocus = document.activeElement;
// ...
expect(elementWithFocus).toBe(debugElement.nativeElement);
...