2014-02-06 141 views
1

我已經開始了一個名爲omniprop的開源Scala項目。我目前正在探索的功能是如何讓項目的用戶堆疊JVM樣式的屬性提供程序。例如,您可能希望在java.lang.System,Lift的util.Prop和Typesafe的配置庫中查找屬性。由於omniprop的一些其他約束/特性,我需要這個堆棧配置駐留在一個已知對象中,所以庫的其他部分可以從這個堆棧中檢索屬性。Scala庫初始化設計

爲了使omniprop正常工作,需要在訪問任何屬性之前由庫的用戶調用此配置。因此,任何使用我的庫的項目都需要一個可以設置提供者堆棧的引導程序/初始化程序。此初始配置代碼的示例如下所示:

import com.joescii.omniprop.providers._ 
PropertyProviders.configure(List(
    SystemPropertyProvider, 
    LiftPropsProvider 
)) 

我面臨的挑戰是特別針對測試。爲了讓使用omniprop的項目的測試代碼正常工作,必須以某種方式在運行任何測試之前運行上述代碼。目前,我沒有看到用sbt或我熟悉的任何測試庫(如scalatest,scalacheck或specs2)來執行此操作的乾淨方法。實際上,每個測試套件都需要調用上面的代碼片段,這當然不是理想的。

這個問題的另一種方法是Lift所做的,其中每個項目必須有一個名爲bootstrap.liftweb.Boot的類,庫被調用來設置一切。我發現這是一個合理的方法來處理像Lift這樣的Web框架,但對於一個小小的屬性幫助程序庫似乎太多了。

我真的在這裏有兩個問題:

  1. 我怎麼能有SBT調用上面的設置代碼與正確的類加載器的所有測試運行之前?
  2. 更重要的是,這是需要初始化的庫的最佳設計,還是有更好的方法?
+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 { 
    // ... 
} 
+0

此功能完全是爲了作者的目的。 – dmitry

1

您可以將初始化代碼放入特質構造函數中,並讓您的測試從該特性中擴展。

另一種方法是將該配置作爲默認配置,如果未設置配置,則在第一次調用庫代碼時使用該配置。這將涵蓋測試和非測試場景。

混合的方法是讓你的sbt測試配置設置一個系統屬性。如果設置了該系統屬性並且沒有設置配置,則將在第一次調用庫代碼時使用測試配置。