我已经启动了一个名为omniprop的开源Scala项目。我目前正在探索的功能是如何允许项目用户堆叠JVM样式的属性提供程序。例如,您可能希望在java.lang.System
,Lift的util.Prop
和Typesafe的配置库中查找属性。由于omniprop的一些其他约束/特性,我需要将此堆栈配置驻留在已知对象中,因此库的其他部分可以从此堆栈中检索属性。
为了使omniprop正常工作,在访问任何属性之前,需要由库的用户调用此配置。因此,任何使用我的库的项目都需要一个可以设置提供者堆栈的bootstrap / initializer。此初始配置代码的示例如下所示:
import com.joescii.omniprop.providers._
PropertyProviders.configure(List(
SystemPropertyProvider,
LiftPropsProvider
))
我面临的挑战特别是测试。为了使用omniprop的项目的测试代码能够工作,它必须以某种方式在运行任何测试之前运行上面的代码。目前,我没有看到使用sbt或我熟悉的任何测试库(如scalatest,scalacheck或specs2)执行此操作的简洁方法。实际上,人们需要在每个测试套件中调用上面的代码片段,这当然不是理想的。
此问题的另一种方法是Lift所做的,其中每个项目都必须有一个名为bootstrap.liftweb.Boot
的类,库调用它来设置所有内容。我发现这是一个合理的方法来处理像Lift这样的Web框架,但对于一个小的属性助手库来说似乎太过分了。
我真的有两个问题:
答案 0 :(得分:2)
使用ScalaTest,当我不得不做类似的事情时,我创建了一个扩展BeforeAndAfterAll
的特征,我将其混合到需要它的每个套件中。
trait Configure extends Suite with BeforeAndAfterAll {
override def beforeAll() { PropertyProviders.configure(/*...*/); }
override def afterAll() { PropertyProviders.configure(/*...*/); }
}
你只需像其他任何特质一样混合它
trait FooSpec extends Spec with Configure {
// ...
}
答案 1 :(得分:1)
您可以将初始化代码放在特征构造函数中,让测试从该特征扩展。
另一种方法是将该配置作为默认配置,如果未设置配置,则在第一次调用库代码时使用它。这将涵盖测试和非测试场景。
混合方法是让您的sbt测试配置设置系统属性。如果设置了该系统属性并且未设置任何配置,那么将在第一次调用库代码时使用测试配置。