繁体   English   中英

如何在 Scala 中使用 JUnit ExpectedException?

[英]How can I use JUnit ExpectedException in Scala?

我希望能够在 Scala 中使用 JUnit 4.7 的ExpectedException @Rule 但是,它似乎没有捕捉到任何东西:

import org.junit._

class ExceptionsHappen {

  @Rule 
  def thrown = rules.ExpectedException.none

  @Test
  def badInt: Unit = {
    thrown.expect(classOf[NumberFormatException])
    Integer.parseInt("one")
  }
}

这仍然失败,并出现NumberFormatException

为了在 Scala 中使用 JUnit 4.11,您应该对注释进行元注释,以便注释仅应用于(合成)getter 方法,而不是基础字段:

import org.junit._
import scala.annotation.meta.getter

class ExceptionsHappen {

  @(Rule @getter)
  var thrown = rules.ExpectedException.none

  @Test
  def badInt: Unit = {
    thrown.expect(classOf[NumberFormatException])
    Integer.parseInt("one")
  }
}

编辑:在 JUnit 4.11 发布之后,您现在可以使用@Rule注释方法。

你会像这样使用它:

private TemporaryFolder folder = new TemporaryFolder();

@Rule
public TemporaryFolder getFolder() {
    return folder;
}

对于早期版本的 JUnit,请参阅下面的答案。

——

不,您不能直接从 Scala 使用它。 该字段需要是公共的和非静态的。 org.junit.Rule

public @interface Rule: Annotates fields that contain rules. Such a field must be public, not static, and a subtype of TestRule.

您不能在 Scala 中声明公共字段。 所有字段都是私有的,并且可以由访问者访问。 请参阅此问题的答案。

除此之外,已经有一个junit的增强请求(仍然开放):

扩展规则以支持@Rule public MethodRule someRule() { return new SomeRule(); }

另一种选择是允许非公共字段,但这已经被拒绝:允许在非公共字段上使用 @Rule 注释

所以你的选择是:

  1. 克隆junit,并实现第一个建议,方法,并提交拉取请求
  2. 从实现 @Rule 的 java 类扩展 Scala 类

——

public class ExpectedExceptionTest {
    @Rule
    public ExpectedException thrown = ExpectedException.none();
}

然后从中继承:

class ExceptionsHappen extends ExpectedExceptionTest {

  @Test
  def badInt: Unit = {
    thrown.expect(classOf[NumberFormatException])
    Integer.parseInt("one")
  }
}

哪个工作正常。

作为 Scala 的新手,我只是使用了一个非常简单的解决方法:如果没有抛出预期的异常,则显式捕获异常并失败。

下面是一个示例骨架:

try {
  *your code that should throw an exception*
  fail("Did not generate *the.Exception.you.expect*")
} catch {
  case t: *the.Exception.you.expect* => // do nothing, it's expected :)
}

如果 Scala 有类似静态导入的东西,那么catch-exception是 JUnit 4.7 的 ExpectedException @Rule 的替代品。

我仍在使用 JUnit 4,发现 @Juh_ 的评论很有启发性。 这在 Scala 2.11.0 中有效。

import org.junit.rules.ExpectedException
import org.junit.{Rule, Test}

import scala.reflect.{ClassTag, classTag}

class DeleteMe {

  object Thrower {
    def throwException[R <: Throwable: ClassTag](message: String): Unit = {
      throw classTag[R].runtimeClass.getConstructor(classOf[String]).newInstance(message).asInstanceOf[R]
    }
  }

  @Rule
  def exceptionRule:ExpectedException = ExpectedException.none()

  @Test(expected = classOf[Exception])
  def checkConversionExceptions = {
    val myMessage = "My Message"
    exceptionRule.expectMessage(myMessage)
    Thrower.throwException[Exception](myMessage)
    ()
  }
}

在不了解 JUnit 规则的情况下,也没有对其进行测试,因为我手头没有合适的设置,所以我冒昧地建议把它扔进一个 val。 我猜它的某个成员用某种东西初始化,然后它得到某种状态,然后其他一些机器根据某种东西检查状态。 你总是在创造新的,并不断忘记期望。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM