У меня есть приложение angular, для которого я пытаюсь создать модульный тест. Существует особый метод, который создает наблюдаемое через сложную цепочку наблюдаемых каналов и обещаний, а затем подписывается на созданный наблюдаемый объект. Мне нужно убедиться, что вызов метода выполняется внутри подписки.
Структура примерно такая:
private obs$: Observable<T>;
private subscription: Subscription;
methodToTest(): void {
this.obs$ = from( ... ).then( /* chain of piped observables */ );
this.subscription = this.obs$
.subscribe(
(value: T) => {
// bunch of logic
methodToBeVerifiedWasCalled();
},
(error) => { /* error handling */ }
);
}
Мой тест пока выглядит так:
it('the method to be verified is successfully called', () => {
// various mocking set up
this.mockApi.methodThatReturnsAPromise.and.returnvalue(Promise.resolve());
// etc.
this.classUnderTest.methodToTest();
// assertions for the various mocks...
expect(this.mockApi.methodThatReturnsAPromise).toHaveBeenCalled();
// etc.
// assert that the target method was called:
expect(this.classUnderTest.methodToBeVerifiedWasCalled).toHaveBeenCalled();
expect(this.classUnderTest.subscription).toBeDefined();
});
Конечно, этот тест терпит неудачу при последних утверждениях, потому что methodToBeVerifiedWasCalled
фактически вызывается внутри блока подписки, и тест просто выполняет его синхронно. (Здесь classUnderTest
- шпионский объект, за которым шпионят methodToBeVerifiedWasCalled
.)
Поскольку метод присваивает значение наблюдаемому, я не могу просто подписаться на classUndertest.obs$
в асинхронном тесте и проверить возвращаемое значение (что в любом случае не помогает решить проблему). Как я могу проверить, что метод внутри блока подписки называется?
Я не могу изменить исходный код, только тесты.