Как вы пишете модульный тест для оператора углового буферизации RxJS?

#angular #unit-testing #rxjs #buffertime

Вопрос:

У меня есть простая подписка на тему с буферным временем:

 import { Injectable } from '@angular/core';
import { Subject, Observable, of, Subscription } from 'rxjs';
import { bufferTime, concatMap } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class AService {
    private someSubject$ = new Subject<boolean>();
    private someObservable$ = this.someSubject$.asObservable();
    private sub: Subscription;

    constructor() {
        this.setupObservables();
    }

    nextSomeSubject() {
        this.someSubject$.next(true);
    }

    private setupObservables() {
        if (this.sub amp;amp; !this.sub.closed) {
            this.sub.unsubscribe();
        }

        this.sub = this.someObservable$
            .pipe(
                bufferTime(333),
                concatMap(requests => this.doSomething$(requests))
            )
            .subscribe();
    }

    private doSomething$(requests): Observable<unknown> {
        return of(true);
    }
}
 

И мое приложение делает именно то, что я ожидаю. Он вызывает doSomething каждые 333 миллиметра (до тех пор, пока в буфере что-то есть. У меня есть фильтр, который я не показываю.)

Но я не могу понять, как заставить модульный тест запустить это без повторного вызова функции, которую уже вызвал конструктор службы.

 import { discardPeriodicTasks, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { AService } from './service';

describe('', () => {
    let service: AService;

    beforeEach(() => {
        TestBed.configureTestingModule({});
        service = TestBed.inject(AService);
    });

    fit('should trigger in 333 millis', fakeAsync(() => {
        const doSomethingSpy = spyOn(service, <any>'doSomething


Комментарии:

1. Ваш тест не проваливается, он выдает ошибку.

2. @PetrAveryanov это псевдокод для представления ситуации. Он не исполняется как есть. Мой запущенный код нигде не ошибается.

3. 99% это означает, что ваш псевдокод не представляет вашей проблемы. И 1% , что это какая-то проблема, связанная с версией/средой, вызывает простой тест с буферным временем.

4. @PetrAveryanov ты прав. Проблема в том, что в тесте есть что-то другое, что установка в конструкторе не выполняется. Я должен явно вызвать метод, который настраивает это наблюдаемое ПОСЛЕ настройки тестового стенда, даже если конструктор выполняется. Я изменю свой psuedo-код

).and.callThrough();

// Even though this function is called by the constructor,
// and executes before you get here in the test if you console.log it,
// the unit test fails if you don't call this directly?!
service['setupObservables']();

service.nextSomeSubject();
tick(333);
expect(doSomethingSpy).toHaveBeenCalled(); // failure
discardPeriodicTasks();
}));
});

Комментарии:

1. Ваш тест не проваливается, он выдает ошибку.

2. @PetrAveryanov это псевдокод для представления ситуации. Он не исполняется как есть. Мой запущенный код нигде не ошибается.

3. 99% это означает, что ваш псевдокод не представляет вашей проблемы. И 1% , что это какая-то проблема, связанная с версией/средой, вызывает простой тест с буферным временем.

4. @PetrAveryanov ты прав. Проблема в том, что в тесте есть что-то другое, что установка в конструкторе не выполняется. Я должен явно вызвать метод, который настраивает это наблюдаемое ПОСЛЕ настройки тестового стенда, даже если конструктор выполняется. Я изменю свой psuedo-код