Ожидание завершения Future, прежде чем делать утверждения

У меня есть приложение Scala Play, и один из контроллеров запускает Future, который ведет журнал. У меня есть простая функция обратного вызова, которая выполняется, когда Future завершается.

Я написал тест, чтобы проверить, происходит ли это ведение журнала. Грубая логика такова:

feature{

  scenario{
    Given()
      // set up the call
    When()
      // make a FakeRequest via reverse routing - logging will done in a separate thread via a Future
    Then()
      Thread.sleep(50) // sleep to allow logging to finish
      // check if the logging has been done

Проблема в Thread.sleep. Я добавил этот вызов, чтобы заблокировать основной поток тестирования, чтобы дать достаточно времени, чтобы пройти для Future, который выполняет регистрацию в отдельном потоке для завершения, прежде чем фактически выполнять проверки, чтобы увидеть, была ли выполнена регистрация.

Мой вопрос в том, есть ли лучший способ сделать это? На самом деле, если мое приложение работает, а ведение журнала занимает слишком много времени, то основной поток, управляющий приложением, не завершится до тех пор, пока не завершится Future, который ведет ведение журнала в отдельном потоке. Так что я не вижу проблемы с вызовом Thread выше, чтобы имитировать это. Но я просто хочу подтвердить, правильно ли это.

Для меня абсолютно нет другого пути, кроме как сделать это. Если я попытаюсь воспроизвести поведение приложения в реальности с помощью своего теста, то основной поток теста должен завершиться и завершиться, даже если будущее для ведения журнала все еще продолжается; обратного звонка в тесте нет и быть не должно.


person M.K.    schedule 08.01.2016    source источник
comment
Я бросил свой ответ. Принимая во внимание, как вы это прокомментировали, я бы предложил: либо сделать ссылку доступной в тестах, либо обновить некоторую глобальную переменную о будущих результатах (например, количество опубликованных сообщений журнала).   -  person vvg    schedule 08.01.2016
comment
Можете ли вы использовать CallingThreadDispatcher для создания тестов? синхронный?   -  person jkinkead    schedule 08.01.2016
comment
@jkinkead, синхронизация теста не будет воспроизводить поведение приложения (которое является асинхронным). Для меня тестирование не должно отклоняться от того, как приложение должно вести себя в реальности.   -  person M.K.    schedule 08.01.2016
comment
@rumoku, нет, я не могу использовать глобальные переменные и т. д.   -  person M.K.    schedule 08.01.2016


Ответы (1)


Предполагая, что вы используете ScalaTest ; вы можете использовать конструкцию whenReady; который периодически проверяет переданное будущее, пока оно не будет готово или не будет превышено настроенное время ожидания; см. http://www.artima.com/docs-scalatest-2.0.M5/org/scalest/concurrent/Futures.html

http://doc.scalest.org/2.0/index.html#org.scalest.concurrent.ScalaFutures

person Vikas Pandya    schedule 08.01.2016
comment
Нет, я не могу. У меня нет дескриптора будущего, который ведет журнал. - person M.K.; 08.01.2016