3

ScalaTestを使用して、基本的に「例外をスローしないか、可能な例外のリストの1つをスローする必要がある」と述べているプロパティを作成しようとしていますGeneratorDrivenPropertyChecks。問題は、 を論理和と組み合わせることができなかったことですnoException。したがって、私ができる最善の方法は、この醜いテストです。

it should "not throw unexpected exceptions" in {
  forAll { (s: String) =>
    try { parse(s) }
    catch { case e:Throwable => e shouldBe a [ParsingFailedException] }
    true shouldBe true // prevent compile error
}}

代わりに私が見たいのは、次のように読むことです

it should "not throw unexpected exceptions" in {
  forAll { (s: String) => {
    (noException should Be thrownBy) or (a [ParsingFailedException] shouldBe thrownBy) { parse(s)  }
}}
4

1 に答える 1

3

例外を値として使用し、例外フローを制御したくないため、 の値を使用scala.util.Tryしてアサーションを作成できますTry。したがって、 を呼び出す代わりに、 を呼び出すparse(s)ことができますTry(parse(s))

残念ながら、現在は値がラップされているため、カスタム マッチャーを作成する以外に、述語をアサートするクリーンな方法を思いつきません。特定の例では、カスタムマッチャーは次のようになります。

class FailAsMatcher[E <: Throwable](t: Class[E]) extends Matcher[Try[Any]] {
  def apply(theTry: Try[Any]) =
    MatchResult(
      theTry.isFailure && (theTry.failed.get.getClass == t),
      s"did not fail as a $t",
      s"did fail as a $t"
    )
}

は共変であるためTry、カスタムマッチャーのジェネリック型を と定義できますTry[Any]。マッチャーは、指定Failure[Any]されたタイプを除いて、その失敗のインスタンスのみに一致します。これを次のように呼び出すことができます。

it should "not throw unexpected exceptions" in {
  forAll { (s: String) =>
    Try(parse(s)) should ( be ('success) or failAs(classOf[ParsingFailedException]))
  }
}

def failAs[E <: Throwable](t: Class[E]) = new FailAsMatcher[E](t)

ここで、予期しない例外が発生した場合、エラーは次のようになります。

TestFailedException was thrown during property evaluation.
  Message: Failure(java.lang.NullPointerException) was not success, and did not fail as a class ParsingFailedException
于 2014-12-01T23:42:19.530 に答える