#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-код