Исключение не обрабатывается в методе восстановления - PullRequest
0 голосов
/ 25 мая 2020

Этот метод выдает exception

  @throws(classOf[QuestionNotFoundException])
  def getQuestionFromQuestionID(questionKey: PracticeQuestionKeys) = {
    logger.trace(s"getting question with keys ${questionKey}")
    val practiceQuestionFuture: Future[Option[PracticeQuestion]] = findOne(questionKey)
    for (questionOption <- practiceQuestionFuture) yield {
      questionOption.fold(throw QuestionNotFoundException())(question => {
        logger.trace("got question " + question)
        question
      })
    }
  }

Я использую его, как показано ниже

def function1 = {
...
val res = for{existingQuestion <- questionsRepository.getQuestionFromQuestionID(questionKey){..}
res.recover {
                     case exception => {
                       logger.trace(s"exception ${exception}")
                       Ok(Json.toJson(JsonResultError(messagesApi("error.answerAdditionFail")(langs.availables(0))+". "+exception.getMessage())))
                     }
...
}

Я хочу проверить, что function1 обрабатывает выброшенное исключение. Я написал следующий тестовый пример

"function" should {
    "should return error if the question id is not correct" in {
      ...

      when(answerTestEnv.mockPracticeQuestionsRepository.getQuestionFromQuestionID(ArgumentMatchers.any[PracticeQuestionKeys])).thenThrow(
        QuestionNotFoundException()
      )




      val response:Accumulator[ByteString,Result] = controller.function1(request)
      //note that run is how accumulator gets the data and starts processing it. no parameter means no data
      val resultOfAccumulatorRun:Future[Result] = response.run(ByteString(body))
      val responseBody = contentAsJson(resultOfAccumulatorRun)(Timeout(Duration(5000,"millis")),TestEnvImplicits.mat)

      println(s"received response ${responseBody}")
      val result = (responseBody \ "result").get.as[String]

      val additionalInfo = (responseBody \ "additional-info").get.as[String]

      result mustBe "error"
      additionalInfo mustBe components.messagesApi("error.answerAdditionFail")(components.langs.availables(0))+". "+QuestionNotFoundException().msg


    }

}

Но когда я запускаю свой тестовый пример, Exception выдается, но кажется, что res.recover не справляется с этим. Я вижу это в консоли.

Question not found
utilities.QuestionNotFoundException: Question not found
    at controllers.AnswerController.$anonfun$newAnswer$1(AnswerController.scala:428)

Почему t res.recover` не справляется с этим.

1 Ответ

0 голосов
/ 01 июня 2020

частичная функция, переданная в recovery (), вызывается в неудачном Future, но ваше Future - это не неудачное Future, это Future, которое содержит исключение в качестве своего 'успешного' типа результата (на самом деле оно будет вынуждено быть чем-то более похожим на Future [AnyRef], так как это может быть либо Exception, либо PracticeQuestion).

Вероятно, вы не захотите использовать Option.fold () таким образом. Вместо этого попробуйте:

practiceQuestionFuture.flatMap { qOpt =>
          qOpt.map(q => Future(q))
              .getOrElse(Future.failed(QuestionNotFoundException()))
}

(NB: я не рядом с компилятором, чтобы опробовать это прямо сейчас, поэтому я, возможно, допустил синтаксическую ошибку или две, но их должно быть достаточно, чтобы вы начали ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...