JUnit 5:如何断言 Scala 中抛出异常?

问题描述 投票:0回答:4

版本:

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()
java scala unit-testing junit junit5
4个回答
2
投票

您可以通过明确闭包的返回类型,将函数类型

() => 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
否则它们将永远不会运行。


2
投票

如果我们想以 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
投票

为了构建之前的答案,我想编写多行测试代码,而不仅仅是调用 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
      }
    })
  }

}

0
投票

您也可以使用

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
返回异常,因此如果您想测试它是否包含预期文本,您可以从中获取消息。

© www.soinside.com 2019 - 2024. All rights reserved.