我有一个使用FakeApplication和嵌入式mongodb数据库的specs2测试。
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 replicat集,这才有效。现在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
}
}
这不起作用,因为它没有加载任何配置。
我非常感谢任何帮助。感谢。
克里斯
答案 0 :(得分: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);
}
});
}
我不知道Scala方面是否有一个很好的方法,我们正在用java编写所有代码。
答案 1 :(得分: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
}
}
}
答案 2 :(得分:2)
这就是我在Play 2.3.x中的表现
在包中的类GlobalSettings
中定义我的应用程序AppGlobal
(不是根包)
package configs
class AppGlobal extends GlobalSettings {
// Your application global settings
???
}
将应用程序全局设置定义为object Global extends AppGlobal
,用于您的应用程序。
在测试类中,定义测试全局。最后添加测试配置以覆盖或添加到整个应用程序配置:
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"))
}
}
使用上述TestGlobal
FakeApplication(withGlobal = Some(TestGlobal))
答案 3 :(得分:1)
在我的例子中,我只创建了一个基础类,我的所有测试都扩展了。 在创建FakeApplication之前,我定义了设置应用程序配置的系统属性 config.resource 。 然后我将配置结构如下:
application.conf:包含no-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()
}
答案 4 :(得分:0)
使用path
在这里不起作用,因为这是您正在运行的FakeApplication的路径(在某些情况下您可能有不同的路径)。
我建议您在运行Play for test模式时指定test.conf
,例如。
play -Dconfig.file=conf/test.conf
然后会选择test.conf
。然后,您还可以将其包括正常application.conf
并仅覆盖mongo设置。
将“单一目标模式”作为application.conf
中连接到mongodb的默认方式,并覆盖mongob配置以仅在生产配置中使用复制集也许也是有意义的。