Scala 预期异常片段 [英] Scala expected exception snippet
问题描述
我正在尝试模拟常见测试框架(例如 JUnit 或 TestNG)的预期异常行为.
I'm trying to simulate the expected exception behavior of common testing frameworks (e.g. JUnit or TestNG).
这是我目前能想到的(工作中):
Here's what I could come up with so far (working):
trait ExpectAsserts
{
self : {
def fail (message : String)
def success (message : String)
} =>
def expect[T](exceptionClass : Class[T])(test : => Unit)
{
try
{
test
fail("exception not thrown")
}
catch
{
case expected : T => success("got exception " + expected)
case other : Exception => fail("expected "+ exceptionClass + " but " + other + " thrown instead.")
}
}
}
object Main extends ExpectAsserts
{
def main (args : Array[String])
{
expect(classOf[ArithmeticException])
{
throw new IllegalArgumentException // this should print an error message.
}
}
def fail (s : String)
{
System.err.println(s)
}
def success(s : String)
{
System.out.println(s)
}
}
该代码段有一个 main
方法来练习代码.我的问题是抛出的异常进入了第一个模式匹配语句:
The snippet has a main
method that exercises the code. My problem is that the exception thrown enters in the first pattern matching statement:
case expected : T
虽然我实际上是说异常必须是 T
类型,也就是 IllegalArgumentException
.
Although I'm actually saying that the exception has to be of type T
, which would be IllegalArgumentException
.
有什么想法吗?
推荐答案
使用 -unchecked
编译,你会看到一个警告,类型测试 expected: T
will由于类型擦除,总是返回 true.
Compile with -unchecked
and you'll see a warning that the type test expected: T
will always return true, thanks to type erasure.
scala> def foo[T](a: Any) = a match {
| case _: T => "always will match!"
| }
<console>:22: warning: abstract type T in type pattern T is unchecked since it is eliminated by erasure
case _: T => "always will match!"
^
foo: [T](a: Any)java.lang.String
scala> foo[String](0)
res3: java.lang.String = always will match!
看到您传入了类,您可以改用 Class#isInstance
.在您的代码中,这看起来像:
Seeing as you have the class passed in you can use Class#isInstance
instead. In your code, that would look like:
case expected if clazz.isInstance(expected) => success("got exception " + expected)
在一个自包含的例子中.这里我们隐式传递了一个Manifest[T]
,这是一种让编译器传递额外参数来获取类型擦除丢弃的信息的方法:
In a self contained example. Here we pass a Manifest[T]
implicitly, which is a way to get the compiler to pass an extra parameter to obtain the information that type erasure threw away:
scala> def foo[T: ClassManifest](a: Any) = manifest[T].erasure.isInstance(a)
foo: [T](a: Any)(implicit evidence$1: Manifest[T])Boolean
scala> foo[String](new {}) // compiler passes Manifest[String] here
res4: Boolean = false
scala> foo[String]("")
res5: Boolean = true
进一步阅读:
- 如何解决 Scala 上的类型擦除问题?或者,为什么我无法获取我的集合的类型参数?
- https://stackoverflow.com/questions/1332574/common-programming-mistakes-for-scala-developers-to-avoid/1338119#1338119
- 什么是清单Scala 以及您何时需要它?
- Specs2 异常匹配器
这篇关于Scala 预期异常片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!