2012-09-03 35 views
9

我有一個specs2測試,它使用FakeApplication和嵌入式MongoDB數據庫。播放2.0 FakeApplication設置與測試配置

def inMemoryMongoDatabase(name: String = "default"): Map[String, String] = { 
    val dbname: String = "play-test-" + scala.util.Random.nextInt 
    Map(
     ("mongodb." + name + ".db" -> dbname), 
     ("mongodb." + name + ".port" -> EmbeddedMongoTestPort.toString)) 
} 

override def around[T <% Result](t: => T) = { 
    running(FakeApplication(additionalConfiguration = inMemoryMongoDatabase(), additionalPlugins = Seq("se.radley.plugin.salat.SalatPlugin"))) { 
     t // execute t inside a http session 
    } 
} 

的FakeApplication使用在conf目錄和額外的配置可用於爲每個測試創建的測試數據庫的默認application.conf配置。
這是工作找到,直到我們設置了一個mongodb複製集。現在application.conf包含此replicat配置設置

mongodb.default.replicaset { 
host1.host = "localhost" 
host1.port = 27017 
host2.host = "localhost" 
host2.port = 27018 
host3.host = "localhost" 
host3.port = 27019 
} 

由於FakeApplication使用默認的配置測試失敗,因爲replicaset的主機不能被發現。我想爲我的測試有不同的配置,基本上刪除mongodb.default.replicaset條目。如果mongodb.default.replicaset是一個簡單的Map [String,String],可以很簡單,因爲我可以將它添加到additonalConfiguration,但是當我嘗試這樣做時,它會失敗,因爲期望的值類型不是String而是Object。我也嘗試通過path參數向FakeApplication提供一個單獨的test.conf文件。

override def around[T <% Result](t: => T) = { 
    running(FakeApplication(path = new java.io.File("conf/test.conf"), additionalConfiguration = inMemoryMongoDatabase(), additionalPlugins = Seq("se.radley.plugin.salat.SalatPlugin"))) { 
     t // execute t inside a http session 
    } 
} 

因爲它沒有加載任何配置,所以沒有工作。

我將不勝感激任何幫助。謝謝。

克里斯

回答

3

問題是如何使用Play的FakeAppication運行集成測試時指定test.conf文件。在我的集成測試中,我不能撥打play -Dconfig.file=conf/test.conf

我成功地做到這一點:

object FakeSalatApp extends Around { 

def EmbeddedMongoTestPort: Int = 27028 

def inMemoryMongoDatabase(name: String = "default"): Map[String, String] = { 
    val dbname: String = "play-test-" + scala.util.Random.nextInt 
    Map(
    ("mongodb." + name + ".db" -> dbname), 
    ("mongodb." + name + ".port" -> EmbeddedMongoTestPort.toString), 
    ("mongodb." + name + ".replicaset.host1.host" -> "localhost"), 
    ("mongodb." + name + ".replicaset.host1.port" -> EmbeddedMongoTestPort.toString), 
    ("mongodb." + name + ".replicaset.host2.host" -> "localhost"), 
    ("mongodb." + name + ".replicaset.host2.port" -> (EmbeddedMongoTestPort + 1).toString), 
    ("mongodb." + name + ".replicaset.host3.host" -> "localhost"), 
    ("mongodb." + name + ".replicaset.host3.port" -> (EmbeddedMongoTestPort + 2).toString)) 
    } 

override def around[T <% Result](t: => T) = { 
    running(FakeApplication(additionalConfiguration = inMemoryMongoDatabase(), additionalPlugins = Seq("se.radley.plugin.salat.SalatPlugin"))) { 
    t // execute t inside a http session 
    } 
} 
} 
0

使用path不會在這裏工作,因爲這是你正在運行的FakeApplication的路徑(你可能需要在某些情況下,不同的路徑)。

我在你的情況下建議你在爲測試模式運行Play時指定test.conf,例如,

play -Dconfig.file=conf/test.conf 

然後test.conf將被拿起。你也可以讓它包括你的正常application.conf並且只覆蓋mongo設置。

也許在「application.conf」中將「單目標模式」連接到mongodb的默認方式也是有意義的,並且覆蓋mongob配置以僅在生產配置中使用複製集。

10

我們有一個類似的問題加載額外的配置爲我們的集成測試。我們發現填充地圖手動是乏味的,所以我們用下面的辦法:

private Configuration additionalConfigurations; 
@Before 
public void initialize(){ 
    Config additionalConfig = ConfigFactory.parseFile(new File("conf/integration.conf")); 
    additionalConfigurations = new Configuration(additionalConfig); 
} 
@Test 
public void testPropertiesGetLoaded() throws Exception{ 
    running(testServer(3333, fakeApplication(additionalConfigurations.asMap())), HTMLUNIT, new Callback<TestBrowser>(){ 
     public void invoke(TestBrowser browser){ 
      String specificProperty = Play.application().configuration().getString("specific.property"); 
      System.out.println(specificProperty); 
     } 
    }); 
} 

我不知道是否有對事物的斯卡拉側一個很好的方法,我們正在做我們在Java中所有的代碼。

2

這就是我在Play 2.3中所做的。X

  1. 定義我的應用程序GlobalSettings一類AppGlobal在包中(不是根包)

    package configs 
    
    class AppGlobal extends GlobalSettings { 
        // Your application global settings 
        ??? 
    } 
    
  2. 定義應用程序的全局設置,object Global extends AppGlobal所使用你的應用程序。

  3. 在測試類中,定義一個測試全局。測試配置在末尾加上覆蓋或添加到整體應用程序配置:

    object TestGlobal extends AppGlobal { 
        override def onLoadConfig(config: Configuration, 
              path: File, 
              classloader: ClassLoader, 
              mode: Mode): Configuration = { 
        config ++ configuration ++ 
          Configuration.load(path, mode = Mode.Dev, 
              Map("config.file" -> "conf/test.conf")) 
        } 
    } 
    
  4. 創建上述TestGlobal

    FakeApplication(withGlobal = Some(TestGlobal)) 
    
1

在我來說,我只是假的應用創建了一個我所有測試擴展的基類。 在創建FakeApplication之前,我定義了設置應用程序配置的系統屬性config.resource。 然後我就構成我的配置如下:

application.conf:不包含-ENV特定配置

test.conf:包括application.conf並定義配置來運行單元測試

env_local。 CONF:包括application.conf並定義配置來運行應用程序在本地

env_prod.conf:像env_local.conf但對於生產等..

在我的項目,爲方便起見,我已裝箱的腳本local.sh 一個僅運行激活-Dconfig.resource = env_local.conf

@RunWith(classOf[JUnitRunner]) 
class ApplicationTest extends FunSuite with MockitoSugar { 
    System.setProperty("config.resource", "test.conf") 
    val app = Helpers.fakeApplication() 
}