版本:
jdk1.8.0 斯卡拉: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>
我正在关注这个问题,它展示了如何在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()
您可以通过明确闭包的返回类型,将函数类型
() => 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
否则它们将永远不会运行。
如果我们想以 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
为了构建之前的答案,我想编写多行测试代码,而不仅仅是调用 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
}
})
}
}
您也可以使用
intercept
。来自 Scala 文档(针对 Scala 2):
import java.nio.file.NoSuchFileException
class FileTests extends munit.FunSuite {
test("read missing file") {
val missingFile = os.pwd / "missing.txt"
intercept[NoSuchFileException] {
os.read(missingFile)
}
}
}
intercept
返回异常,因此如果您想测试它是否包含预期文本,您可以从中获取消息。