如何在Scala中使用JUnit ExpectedException?

如何在Scala中使用JUnit ExpectedException?,exception,scala,junit,Exception,Scala,Junit,我希望能够在Scala中使用JUnit4.7。然而,它似乎什么都没抓住: import org.junit._ class ExceptionsHappen { @Rule def thrown = rules.ExpectedException.none @Test def badInt: Unit = { thrown.expect(classOf[NumberFormatException]) Integer.parseInt("one") }

我希望能够在Scala中使用JUnit4.7。然而,它似乎什么都没抓住:

import org.junit._

class ExceptionsHappen {

  @Rule 
  def thrown = rules.ExpectedException.none

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

在不了解JUnit规则和测试JUnit规则的情况下,使用
NumberFormatException
仍然会失败,因为我手头没有合适的设置,所以我会冒险出去,建议将其扔进val。
我猜它的某个成员用某个东西初始化,然后它得到某个状态,然后其他一些机器根据某个东西检查状态。您总是在创建新的方法,却总是忘记期望值。

编辑:JUnit4.11发布后,现在可以使用
@Rule
注释方法

您将像这样使用它:

private TemporaryFolder folder = new TemporaryFolder();

@Rule
public TemporaryFolder getFolder() {
    return folder;
}
有关JUnit的早期版本,请参见下面的答案

--

不,您不能直接从Scala使用它。该字段必须是公共的和非静态的。从…起

public@interface Rule:注释包含规则的字段。这样的字段必须是公共的,而不是静态的,并且是TestRule的子类型。

不能在Scala中声明公共字段。所有字段都是私有的,可由访问者访问。看看这个问题的答案

除此之外,junit已经有一个增强请求(仍处于打开状态):

另一个选项是允许使用非公共字段,但此选项已被拒绝:

因此,您的选择是:

  • 克隆junit,实现第一个建议和方法,并提交一个请求
  • 从实现@Rule的java类扩展Scala类
  • -

    然后从中继承:

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

    这是正确的。

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

    要在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")
      }
    }
    

    作为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 :)
    }
    

    我仍然在使用JUnit4,并且发现@Juh_的评论很有启发性。这在Scala 2.11.0中有效

    import org.junit.rules.ExpectedException
    导入org.junit.{Rule,Test}
    导入scala.reflect.{ClassTag,ClassTag}
    类删除我{
    物体投掷器{
    def throwException[R为清晰起见:它(现在)在scala上工作(但仅适用于方法:
    @Rule def myRule=…
    ,而不适用于
    @Rule val myRule=…
    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 :)
    }