JUnit 5:如何断言Scala中引发了异常?

时间:2018-08-22 16:04:27

标签: java scala unit-testing junit junit5

版本:

jdk1.8.0 Scala:2.11

<properties>
 <junit.jupiter.version>5.2.0</junit.jupiter.version>
  <junit.platform.version>1.2.0</junit.platform.version>
</properties>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-all</artifactId>
  <version>1.9.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <version>${junit.jupiter.version}</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>${junit.jupiter.version}</version>
  <scope>test</scope>
</dependency>

我正在遵循此question,它显示了如何在Java中使用junit 5声明异常。

当我尝试在Scala中执行相同操作时:

val closureContainingCodeToTest = () -> myClass.myMethod(data)   // or     val closureContainingCodeToTest = () => myClass.myMethod(data)
assertThrows(classOf[MyException], closureContainingCodeToTest)

我收到此错误:

 Error:(89, 48) type mismatch;
 found   : () => Unit
 required: org.junit.jupiter.api.function.Executable
    assertThrows(classOf[MyException], closureContainingCodeToTest)

这可能是一个非常简单的问题,但是我找不到如何在Scala中为Java Executable对象创建Scala闭包。

编辑:

添加一个简单的完整测试:

package com.my.lib

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable

class myTest {

  @Test
  def myTest = {
    val closureContainingCodeToTest:Executable = () => throw new RuntimeException()
    assertThrows(classOf[RuntimeException], closureContainingCodeToTest)
  }
}

我收到以下错误:

Error:(11, 53) type mismatch;
 found   : () => Nothing
 required: org.junit.jupiter.api.function.Executable
    val closureContainingCodeToTest:Executable = () => throw new RuntimeException()

3 个答案:

答案 0 :(得分:0)

您可以通过明确说明闭包的返回类型(即),将函数类型() => myClass.myMethod(data)强制转换为Executable。添加Executable

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable

class MyClassTests {

  val closureContainingCodeToTest: Executable = () => (new MyClass).myMethod(data)

  @Test
  def throwsExceptionWhenCalled(): Unit = {
    assertThrows(classOf[MyException], closureContainingCodeToTest)
  }

}

或者,如果您内联它,则甚至不需要显式。

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test

class MyClassTests {

  @Test
  def throwsExceptionWhenCalled(): Unit = {
    assertThrows(classOf[MyException], () => (new MyClass).myMethod(data))
  }

}

还请注意,您的测试方法需要返回Unit,否则它们将永远无法运行。

答案 1 :(得分:0)

如果我们要使用 Junit 5 样式-您可以按照以下代码进行操作:

import org.junit.jupiter.api.{DisplayName, Test}
import org.junit.runner.RunWith
import org.scalatest.junit.{JUnitRunner, JUnitSuite}

@RunWith(classOf[JUnitRunner])
class Junit_5_Test extends JUnitSuite{

  object ExceptionTest {
    @throws(classOf[RuntimeException])
    def throwRunEx = throw new RuntimeException
  }

  @Test
  @DisplayName("Example with JUnitSuite")
  def throwsExceptionWhenCalled_With_JUnitSuite() {
    import ExceptionTest._
    assertThrows[RuntimeException]{ throwRunEx}
  }

}

要这样做-您需要在您的build.sbt中加入它:

"org.junit.jupiter" % "junit-jupiter-api" % "5.2.0" % Test,
 "org.scalatest" %% "scalatest" % "3.2.0-SNAP10" % Test

答案 2 :(得分:0)

要以先前的答案为基础,我想编写多行测试代码,而不仅仅是调用MyClass.myMethod(data)

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable

class MyClassTest {

  @Test
  def throwsExceptionWhenCalled(): Unit = {
    assertThrows(classOf[MyException], new Executable {
      override def execute(): Unit = {
        val data = generateBadData()
        new MyClass().myMethod(data) // throws MyException
      }
    })
  }

}