要求用户最终调用方法

时间:2017-02-17 12:08:04

标签: scala

假设我有这样的课程:

case class Test(pars: Seq[Int] = Seq()) {
  def require(p: Int) = copy(pars = p +: pars)

  def execute() = {assert(???)}
}

打算像这样使用:

Test().require(1).require(2).execute()

我在测试中使用它。有时我会忘记调用execute()来使测试通过,因为测试代码根本没有执行。

是否有可能创建支票通知我这个?我尝试过隐式转换为unit,但它没有应用,使用了默认编译器:

implicit def toUnit(setup: Test): Unit = setup.execute() // or ???

这不是一个大问题,我可以通过更加小心来解决它,但有一个编译器(甚至运行时)来警告我会使它更容易。创建或执行测试的实际方法并不重要,可以更改,它不必是案例类及其成员。

3 个答案:

答案 0 :(得分:3)

一种可能的解决方案可能是重构这些内容:

sealed abstract class Test private (pars: Seq[Int] = Seq()) {
  def require(p: Int): Test = new Test.Impl(pars = p +: pars)
  private def execute(): Unit = println("Execute!")
}
object Test {
  def apply(f: Test => Test) = f(new Test.Impl()).execute()

  private class Impl(pars: Seq[Int] = Seq()) extends Test(pars)
}

Test {
  _.require(1).require(2)
}

解决方案的想法是隐藏Test构造函数,以便能够调用它的人可以保证execute始终与它配对。

答案 1 :(得分:1)

您可以使用Unit编译器选项为所有(非-Ywarn-value-discard)类型执行此操作。如果您想将其限制为Test,则可以使用Wart Remover

答案 2 :(得分:0)

经过一些实验后,我找到了一个解决方案,它允许我在测试设置之前而不是之后编写执行,这样我就更容易忘记了:

object execute {
  def --(setup: Test) = setup.execute()
}

execute -- Test().require(1)