2011-10-23 7 views
6

私は昨日Scalaの学習を始めました。新しい言語を学ぶときに好きなことの1つは、マイクロTDDライブラリを作成しようとしていることです。Scala - "assertThrows"メソッドはどのように行うのですか?

これは私がこれまでに得たものである:assertため

def assert(condition: Boolean, message: String) { 
    if(!condition){ throw new AssertionError(message) } 
} 

def assertThrows[E](f: => Unit) { 
    try { 
    f 
    } catch { 
    case e: E => { return } 
    case _: Exception => { } 
    } 
    throw new AssertionError("Expected error of type " + classOf[E]) 
} 

コードはうまく動作しますが、私はassertThrowsには二つの問題を抱えています。

  • 最後の行にEを使用できないようです。私が何をしても、class type expected but E found errorが得られます。
  • 私は最後の行(例えば、throw new AssertionError("error expected")ことによってそれを置き換える)からEを削除した場合、私はこれを取得:warning: abstract type E in type pattern is unchecked since it is eliminated by erasure

私は私がいる二つの問題は、おそらく方法スカラ座(とと関連していると思いますjava)抽象型を扱い、どのようにそれらが行われます。

私は自分のassertThrowsを修正できますか?

ボーナスポイント:「ブロックタイプ」(f: => Unit)を指定する方法は正しいですか?

+1

私はずっと前に質問したことがあります:http://stackoverflow.com/questions/7699709/scala-expected-exception-snippet –

答えて

8

Java仮想マシンは型消去によってジェネリックを実装しているので、メソッド本体の中でJVMは実際にはE型のことを知らないので、このAssertThrowsメソッドはあなたが望むように動作することができません。あなたは暗黙のうちにそうように、あなたの例外クラスのためのマニフェストを渡す必要があります:

def assertThrows[E](f: => Unit)(implicit eType:ClassManifest[E]) { 

次にあなたが例外をキャッチするかそこらのようなクラス名を取得するために体内でそれを使用することができます。

try { 
    f 
    } catch { 
    case e: Exception => 
     if (eType.erasure.isAssignableFrom(e.getClass)) 
     return; 
    } 
    throw new AssertionError("Expected error of type " + eType.erasure.getName) 
} 

感謝私にこれを行う方法を示すためにthe Spring framework's AssertThrows classに。

+0

あなたの答えをありがとう。あなたは使用例を含めることができますか?私はそれを働かせることができません。 – kikito

+0

心配しないで、私はそれを働かせました(一つの答えを加えました)。私はあなたの答えに小さな誤字を編集し、それを正しいものとしてマークしています。 – kikito

0

私はケンの答えのおかげで働くこの事を得た:

class AssertException(msg: String) extends Exception(msg: String) 

def assertThrows[E](f: => Unit)(implicit eType:ClassManifest[E]) { 
    try{ 
    f 
    } catch { 
    case e: Exception => 
    if(eType.erasure.isAssignableFrom(e.getClass)) { return } 
    } 
    throw new AssertException("Expected error of type " + eType.erasure.getName) 
} 

/* examples of usage */ 

assertThrows[NullPointerException]{ throw new NullPointerException() } // ok 
assertThrows[AssertException] { assertThrows[Exception]{ } } // ok! 

おかげでたくさん!

+0

本当に素晴らしい! –

関連する問題