Play 2.0 FakeApplication setup with test configuration

若如初见. 提交于 2019-12-03 03:45:30

We had a similar problem loading extra configurations for our integration tests. We found populating maps manually to be tedious so we used the following approach:

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

I don't know if there is a nice method on the Scala side of things, we are doing all our code in java.

The problem is how to specify the test.conf file when running an intergration test using Play's FakeAppication. In my integration test I cannot call play -Dconfig.file=conf/test.conf.

What I managed to do is this:

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

This is how I did it in Play 2.3.x

  1. Define my application GlobalSettings in a class AppGlobal in a package (not the root package)

    package configs
    
    class AppGlobal extends GlobalSettings {
      // Your application global settings
      ???
    }
    
  2. Define application global settings as object Global extends AppGlobal which is used your application.

  3. In the test class, define a test global. The test configuration is added at the end to override or add to the overall application configuration:

    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. Create the fake application with the above TestGlobal

    FakeApplication(withGlobal = Some(TestGlobal))
    

In my case I have simply created a base class that all my tests extend. Right before creating the FakeApplication I define the system property config.resource that sets the application's configuration. Then I have structured my configurations as follow :

application.conf : contains no-env specific configurations

test.conf : includes application.conf and defines configurations to run the unit tests

env_local.conf : includes application.conf and defines configurations to run the application locally

env_prod.conf : like env_local.conf but for production etc ...

In my project, for convenience I have crated a script local.sh that simply runs 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()
}

Using path won't work here, since this is the path of the FakeApplication you're running (you might have a different path in some cases).

What I'd suggest in your case is to specify a test.conf when running Play for test mode, like e.g.

play -Dconfig.file=conf/test.conf

Then test.conf will be picked up. You could then also have it include your normal application.conf and override just the mongo settings.

Perhaps it would also make sense to have the "single target mode" the default way of connecting to mongodb in your application.conf, and overwrite the mongob configuration to use a replicaset only in a production configuration.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!