Ng-select Интеграционный тест не пройден, если выбран вариант - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь написать правильный тест для моего пользовательского компонента ng-select.Компонент работает, как и ожидалось, но я с трудом пытаюсь протестировать его и не могу найти решение.Пробовал много способов исправить ошибку, но я продолжаю набирать Error: 1 timer(s) still in the queue. сразу после выбора опции.Буду признателен за любую помощь.

Component

@Component({
  selector: 'dp-auto-complete',
  templateUrl: './auto-complete.component.html',
  styleUrls: ['./auto-complete.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => AutoCompleteComponent),
      multi: true
    }
  ]
})
export class AutoCompleteComponent implements OnInit, OnDestroy, ControlValueAccessor {

  @Input() apiMethod: string;
  @Input() placeholder: string;
  @Input() labelProps: string[];
  @Input() callApi = true;
  @Output() selectedItem = new EventEmitter<any>();

  loading = false;
  selected: any;
  disabled: boolean;
  items$: Observable<any>;
  input$ = new BehaviorSubject('');

  constructor(private api: ApiService) {
  }

  ngOnInit() {
    this.placeholder = this.placeholder || 'Select items';
    if (this.callApi) {
      this.onSearch();
    }
  }

  ngOnDestroy() {
    this.input$.complete();
  }

  setDisabledState(isDisabled: boolean) {
    this.disabled = isDisabled;
  }

  registerOnTouched() {
  }

  registerOnChange(fn: any) {
    this.propagateChange = fn;
  }

  writeValue(value: any = null) {
    this.selected = value;
  }

  private propagateChange = (_: any) => {};

  onSearch() {
    this.items$ = concat(
      of([]),
      this.input$.pipe(
        debounceTime(300),
        tap(() => this.loading = true),
        switchMap(term => this.callService(term).pipe(
          catchError(() => of([])),
          tap(() => this.loading = false)
        ))
      )
    );
  }

  private callService(term: string) {
    return this.api[this.apiMethod](term).pipe(map((item: any) => item.results));
  }

  propagateSelected() {
    this.propagateChange(this.selected);
    this.selectedItem.emit(this.selected);
  }
}

Template

<ng-select
    [items]="items$ | async"
    [loading]="loading"
    placeholder="{{placeholder}}"
    [typeahead]="input$"
    [(ngModel)]="selected"
    (change)="propagateSelected()"
    [disabled]="disabled">

  <ng-template ng-label-tmp ng-option-tmp let-item="item">
    <div *ngFor="let label of labelProps" class="d-inline">
      {{item[label]}}
    </div>
  </ng-template>
</ng-select>

Integration TEST

beforeEach(() => {
    apiServiceStub = jasmine.createSpyObj('ApiService', ['searchOrganizations', 'getUser', 'createUser', 'updateUser']);
    apiServiceStub.searchOrganizations.and.returnValue(of({results: [
        {name: 'abc'},
        {name: 'abc123'},
        {name: 'ghc'}
      ]}));

    TestBed.configureTestingModule({
      declarations: [AutoCompleteComponent],
      imports: [FormsModule, NgSelectModule],
      providers: [
        { provide: ApiService, useValue: apiServiceStub }
      ]
    }).compileComponents();
  });

  beforeEach(() => {
    createComponent();
    component.apiMethod = 'searchOrganizations';
    component.labelProps = ['name'];
  });
  it('should ', fakeAsync(() => {
    fixture.detectChanges()
    tick(500)
    fixture.detectChanges()
    selectOption2(fixture, 38, 1)
    tick(500)
    fixture.detectChanges()

    console.log(component.selected)
    }
  ));

Снимки экрана screenshot from 2018-09-25 13-23-02

Я вижу, что значение выбрано и также установлено для компонента, но я понятия не имею, почему в очереди 1 таймер и как его разрешить.

...