0

我们的案例类有几个require语句可以在收到格式错误的输入时抛出异常。这通常很有帮助,但会使编写基于属性的测试变得痛苦,因为我们必须编写满足所有要求的生成器,而不是简单地使用内置的生成器。有没有一种简单的方法可以让 Scala 在测试期间忽略 require 语句?

4

2 回答 2

3

更好的方法是require完全避免,而是编写返回的智能构造函数Either(或者Validation如果你倾向于scalaz。)更好的是case class MyWrapper private (i: Int) extends AnyVal为你的输入类型创建新类型包装器(即),这些包装器带有智能构造函数,使得只能构造有效值。当您为这些定制类型编写生成器时,您可以确保保留所需的不变量。

与其寻找绕过类型系统的方法(通过require在运行时抛出异常),不如让类型系统为您工作。这不仅会使编写基于属性的测试变得更加容易,而且整个系统都会受益。

于 2016-11-02T02:17:08.793 回答
2

不 -require是一种非常简单的方法,正如您从源代码中看到的那样:

def require(requirement: Boolean) {
  if (!requirement)
    throw new IllegalArgumentException("requirement failed")
}

@inline final def require(requirement: Boolean, message: => Any) {
  if (!requirement)
    throw new IllegalArgumentException("requirement failed: "+ message)
}

我建议提供一种单独的方法来构建只有测试使用的类。例如,如果您将构造函数的范围限定为包:

package foo

final case class Foo private[foo] (...)

object Foo {
    def apply(...): Foo = /* put assertions in here */
}

然后你可以把你的 scalacheck 生成器放在同一个包中,让它们使用私有构造函数。

或者,如果您真的想对它感到奇怪,您可以编写自己的代码require来确定是否根据某些全局状态或隐式参数跳过检查。但这似乎不明智。

于 2016-11-02T01:07:14.417 回答