如何在Scala中使用JUnit ExpectedException?

时间:2011-09-08 17:24:33

标签: exception scala junit

我希望能够在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仍然失败。

6 个答案:

答案 0 :(得分:8)

编辑:在发布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中声明公共字段。所有字段都是私有的,并且可以通过访问者访问。请参阅此question的答案。

除此之外,还有针对junit的增强请求(仍处于打开状态):

Extend rules to support @Rule public MethodRule someRule() { return new SomeRule(); }

另一个选择是允许非公开字段,但这已被拒绝:Allow @Rule annotation on non-public fields

所以你的选择是:

  1. 克隆junit,并实现第一个建议,方法,并提交拉取请求
  2. 从实现@Rule
  3. 的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")
      }
    }
    

    正常工作。

答案 1 :(得分:8)

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

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

class ExceptionsHappen {

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

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

答案 2 :(得分:1)

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

以下是示例骨架:

@RequestMapping(value="checkAvailability",method=RequestMethod.POST)
public String checkAvailability(
    @ModelAttribute("courtDetails") CourtDetails courtDetails,
    HttpServletRequest request,
    HttpServletResponse response,
    Model model
)

答案 3 :(得分:0)

在不知道JUnit规则的情况下,并且没有测试它,因为我手边没有适当的设置,我会出现在肢体上并建议将其抛向val。 我猜它的一些成员用某些东西初始化然后它得到一些状态,然后一些其他机器检查状态反对某事。你总是创造新的并且忘记期望。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我仍在使用 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)
    ()
  }
}