RxJs/Ngrx TestSheduler с имитацией пользовательского ввода (Жасмин)
Я тестирую эффекты магазина Ngrx в угловом приложении. Одним из моих эффектов, в качестве побочного эффекта, является модал, который появляется с использованием компонента MatDialog материала.
Что я хочу сделать, так это запустить тест, в котором эффект запускается действием, которое вызывает появление диалогового окна. Затем я хочу протестировать нажатие "да / нет", а затем приступить к проверке конечного действия (или его отсутствия).
Мы используем rxjs-marbles для тестирования нашего магазина.
У RxJs не так уж много примеров, но я понял, что мне нужно использовать TestScheduler для этого типа сценария. Я не уверен, как это работает, хотя. Я провожу много исследований и не добился большого прогресса.
В принципе, как мрамор, это выглядит так:
-a-b-c
где a
это начальное действие, b
это щелчок пользователя в диалоговом окне, и c
результат (c
является необязательным, если пользователь нажимает "нет", то никакого результирующего действия не будет.
Я не прошу никого писать мой код, просто укажи мне правильное направление. Я собираюсь начать читать исходный код для TestScheduler, чтобы понять его лучше, потому что я даже не уверен, что это то, что я должен использовать в этом случае.
По сути, как можно написать такой тест, где есть наблюдаемые потоки в сочетании с моделируемым пользовательским вводом с использованием шариков?
1 ответ
Так что я понял, что поступил неправильно. Это юнит-тест, а не e2e-тест, поэтому мне не нужно тестировать определенные функции пользовательского интерфейса. Поэтому я придумал следующий тест:
it('should show a dialog, and do nothing if the user does not confirm',
() => {
const dialogRef = jasmine.createSpyObj('dialogRef', {
afterClosed: of(false),
});
const action = new AppActions.PromptUserAction();
matDialog.open.and.returnValue(dialogRef);
actions = hot('a', { a: action });
const expected = cold('', {});
expect(effects.promptUserAction$).toBeObservable(expected);
expect(matDialog.open).toHaveBeenCalled();
expect(dialogRef.afterClosed).toHaveBeenCalled();
});
Пояснения:
Создайте dialogRef, который будет возвращен поддельной службой MatDialog (выполняется в настройке beforeEach Angular TestBed, созданной путем предоставления объекта-шпиона следующим образом:
{ provide: MatDialog, useValue: jasmine.createSpyObj( 'MatDialog', ['open'], ), },
Это заглушает метод open, и вы заметите, что вызов open делается для returnValue dialogRef, который мы затем можем использовать в качестве шпиона для возврата желаемой наблюдаемой. Довольно просто, правда.
Остальная часть теста была простой. Надеюсь, это кому-нибудь поможет - вам не обязательно имитировать щелчок, поскольку он неявно присутствует в потоке!