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