我正在寻找一种方法来使用多个输入测试我的 Scala 代码。来自 Java/JUnit,我立即想到了 @RunWith(Theories.class)
。
我被卡住的地方是 @DataPoints 的使用和 Scala 中静态成员/方法的缺失。那么有没有办法在Scala中写出如下代码呢?
@RunWith(classOf[Theories])
class ScalaTheory {
@DataPoints
val numbers = Array(1, 2, 3)
@Theory
def shouldMultiplyByTwo(number : Int) = {
// Given
val testObject = ObjectUnderTest
// When
val result = testObject.run(number)
// Then
assertTrue(result == number * 2)
}
}
我既不专注于 JUnit 也不专注于 Theories,所以如果这个用例有特定于 Scala 的东西,我很乐意使用它。
最佳答案
要完成这项工作,您必须做两件事:使用方法[参见下面的编辑],而不是值,其次,在伴生对象中定义您的@DataPoints
。以下应该有效:
object ScalaTheory {
@DataPoints
def numbers() = Array(1, 2, 3) // note def not val
}
@RunWith(classOf[Theories])
class ScalaTheory {
@Theory
def shouldMultiplyByTwo(number : Int) = {
// Given
val testObject = ObjectUnderTest
// When
val result = testObject.run(number)
// Then
assertTrue(result == number * 2)
}
}
当您在 Scala 中的伴随对象中定义方法或字段时,您会在类中获得一个静态转发器。使用 JAD 反编译:
@Theories
public static final int[] numbers()
{
return ScalaTheory$.MODULE$.numbers();
}
所以这解决了静态问题。但是,当我们使用 val numbers = ...
时,注释不会转移到字段中,而是用于方法。所以使用 def
是可行的。
正如其他人所说,如果您是从头开始开发,则可能值得从 scalatest 等 Scala 框架开始。与 scalatest 的工具集成正在改进(即 maven、Eclipse、Intellij),但它不是 JUnit 的级别,因此在开始之前为您的项目评估它。
编辑:事实上,在 this discussion on scala-user 之后,您可以使用 val,但您需要告诉 scala 编译器将 DataPoints 注释应用于静态转发器:
object ScalaTheory {
@(DataPoints @scala.annotation.target.getter)
val numbers = Array(1, 2, 3)
}
getter 注释表示@DataPoints 注释应该应用于数字字段的访问器方法,即由编译器创建的 numbers() 方法。参见 package target .
关于scala - JUnit 理论和 Scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8572623/