Тестирование исключений в Scala - PullRequest
0 голосов
/ 25 сентября 2019

Я хочу протестировать (в рамках тестирования Intellij Idea) следующий код:

def eval(t: Term): Term = t match {
    case t if isVal(t) => t
    case If(t1,t2,t3) if True == eval(t1) => eval(t2)
    case If(t1,t2,t3) if False == eval(t1) => eval(t3)
    case Succ(t) if isNum(eval(t)) => Succ(eval(t))
    case Pred(t) => eval(t) match {
      case Zero => Zero
      case Succ(v) if isNum(v) => v
      case _ => throw TermIsStuck(Pred(eval(t)))
    }
    case IsZero(t) => eval(t) match {
      case Zero => True
      case Succ(v) if isNum(v) =>False
      case _ => throw TermIsStuck(IsZero(eval(t)))
    }
    case _ => throw TermIsStuck(t)
  }

Для справки вы можете увидеть этот репозиторий .Поэтому я написал следующий тест:

 test("testEval") {

    Arithmetic.term(new Arithmetic.lexical.Scanner("if iszero pred pred 2 then if iszero 0 then true else false else false")) match {
      case Arithmetic.Success(res,next) => assert(eval(res) == True)
      case Arithmetic.Failure(msg,next) => assert(false)
    }

    Arithmetic.term(new Arithmetic.lexical.Scanner("pred succ succ succ false")) match {
      case Arithmetic.Success(res,next) => assert(Arithmetic.eval(res) == TermIsStuck(Succ(False)))
      case Arithmetic.Failure(msg,next) => assert(false)
    }

  }

Получение ошибки:

Succ (False)

fos.Arithmetic $ TermIsStuck: Succ (False)...

Как я могу проверить эту ошибку?Действительно этот тест должен быть пройден ...

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Вы находитесь в Scala, вы не должны бросать исключения, но в скалярном режиме вы можете сделать что-то вроде этого:

a[yourException.type] should be thrownBy yourFunction()

Вы можете сделать лучшую версию этого,

case class Error(exception: Exception){

throw exception

???

}

Или что-то вроде

case object Error

И затем вы проверяете это как:

Error shouldBe yourFunction() 
0 голосов
/ 25 сентября 2019

Похоже, вы не используете какой-либо широко распространенной среды тестирования для scala (такой как scalatest или specs2 ) - очевидной рекомендацией будет использование некоторых.

Однако, если вы хотите придерживаться подхода «без фреймворка», одним из вариантов будет использование старого доброго try .. catch:

val term = Arithmetic.term(
  new Arithmetic.lexical.Scanner("pred succ succ succ false")
)
try {
  val evaluated = term match {
      case Arithmetic.Success(res,next) => Arithmetic.eval(res)
      case Arithmetic.Failure(msg,next) => assert(false)
  }
} catch {
  case TermIsStuck(Succ(False)) => // do nothing, or explicitly mark test as successful
  case _ => assert(false) // any other exception should fail the test
}

Однако, я думаю, что реализация частично сломана - этоникогда не возвращает Arithmetic.Failure, но выдает исключение.Я думаю, что целью Arithmetic.Failure было именно то, чтобы охватить такие случаи.Если это так, то лучшей реализацией будет замена throw TermIsStuck на Arithmetic.Failure(TermIsStuck(...)).

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