Асинхронные тесты методов потока с Mobx
Если вы используете Mobx в рабочем приложении, вы, вероятно, в конечном итоге будете использовать потоки, чтобы упростить работу с действиями.
Короче говоря, это означает замену ваших асинхронных методов оболочкой @flow вокруг функции-генератора, и вместо того, чтобы ждать ваших промисов, вы даете их.
В архитектуре нашего приложения мы используем презентаторы на уровне представления, и именно с их помощью мы тестируем нашу систему (приветствуем Пита Херда из Logic Room).
В каждом из наших тестов мы создаем новый презентер, делаем утверждения, вызываем методы, а затем делаем дальнейшие утверждения, подтверждающие наши тестовые случаи. Здесь нет ничего необычного.
В нашем приложении мы приняли решение в некоторых местах не ждать некоторых звонков, которые делают наши докладчики. Мы хотим, чтобы приложение инициировало вызов, который приведет к вызову API и последующему изменению состояния, но мы не хотим, чтобы поток был активен, пока все это происходит. Мы хотим выстрелить и забыть. Когда состояние в конечном итоге изменится, это будет наблюдаться, и в конечном итоге пользовательский интерфейс приложения будет обновлен.
Теперь возникает проблема.
Как вы тестируете с помощью mobx асинхронный метод, когда тестируемый метод работает и забывает?
Чего мы не хотели делать, так это ждать вызовов наших методов презентаторов, чтобы пройти тест. Здесь нет хвостов, виляющих собакой!
Ответ когда.
when( predicate(), effect() )
В более длинной форме, когда выполняется предикатное условие, эффект запускается.
Это не решило нашу проблему с асинхронностью, поскольку тесты Jest просто запускались после эффекта, завершались и завершали тесты, а затем оценивали эффект, когда предикат возвращал значение true.
В КРАТКОЙ форме when() возвращается обещание. Это означает, что вы можете использовать это как умный метод ожидания в своих тестах и фактически проверить желаемое поведение приложения.
// Usage Example 1 await when (() => presenter.foo === true) OR // Usage Example 2 when (() => presenter.foo === true)) .then(() => {console.log('winning'})
Мы все еще экспериментируем и изучаем, как лучше всего использовать Mobx, поэтому, если вы видите лучший способ решения этой проблемы, не стесняйтесь, дайте мне знать :)