【问题标题】:Play 2.0 FakeApplication setup with test configuration使用测试配置播放 2.0 FakeApplication 设置
【发布时间】:2012-08-28 02:55:06
【问题描述】:

我有一个使用 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 副本集之前,这是有效的发现。现在 application.conf 包含此副本集的配置

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

由于 FakeApplication 使用默认配置,测试失败,因为找不到副本集的主机。我想为我的测试设置不同的配置,基本上删除 mongodb.default.replicaset 条目。如果 mongodb.default.replicaset 是一个简单的 Map[String, String] 这将很容易,因为我可以将它添加到 additonalConfiguration 但是当我尝试这样做时它会失败,因为预期的值类型不是字符串而是对象。我还尝试通过路径参数向 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
    }
}

这也不起作用,因为它没有加载任何配置。

我将非常感谢任何帮助。谢谢。

克里斯

【问题讨论】:

    标签: scala mongodb playframework-2.0 specs2


    【解决方案1】:

    我们在为集成测试加载额外配置时遇到了类似问题。我们发现手动填充地图很繁琐,因此我们使用了以下方法:

    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 编写所有代码。

    【讨论】:

      【解决方案2】:

      问题是如何在使用 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
         }
       }
      }
      

      【讨论】:

        【解决方案3】:

        这就是我在 Play 2.3.x 中的做法

        1. 在包(不是根包)中的类AppGlobal 中定义我的应用程序GlobalSettings

          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))
          

        【讨论】:

          【解决方案4】:

          在我的例子中,我只是创建了一个基类,我的所有测试都扩展了它。 在创建 FakeApplication 之前,我定义了设置应用程序配置的系统属性 config.resource。 然后我将我的配置结构如下:

          application.conf : 包含 no-env 特定配置

          test.conf : 包括 application.conf 并定义运行单元测试的配置

          env_local.conf : 包括 application.conf 并定义配置以在本地运行应用程序

          env_prod.conf : 类似于 env_local.conf 但用于生产等...

          在我的项目中,为方便起见,我创建了一个脚本 local.sh 只需运行 activator -Dconfig.resource=env_local.conf

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

          【讨论】:

            【解决方案5】:

            在这里使用path 不起作用,因为这是您正在运行的 FakeApplication 的路径(在某些情况下您可能有不同的路径)。

            在您的情况下,我建议在运行 Play 以进行测试模式时指定 test.conf,例如

            play -Dconfig.file=conf/test.conf
            

            然后test.conf会被接走。然后,您还可以让它包含您的正常 application.conf 并仅覆盖 mongo 设置。

            也许在application.conf 中将“单一目标模式”作为连接到 mongodb 的默认方式,并覆盖 mongob 配置以仅在生产配置中使用副本集也是有意义的。

            【讨论】:

              猜你喜欢
              • 2013-05-11
              • 2012-10-31
              • 1970-01-01
              • 2023-03-30
              • 2019-01-31
              • 2015-04-29
              • 2012-04-09
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多