2012-09-03 37 views
9

Tôi có một thử nghiệm specs2 sử dụng FakeApplication và cơ sở dữ liệu mongodb được nhúng.Phát 2.0 thiết lập FakeApplication với cấu hình thử nghiệm

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

Các FakeApplication sử dụng cấu hình application.conf mặc định trong thư mục conf và cấu hình bổ sung cho các cơ sở dữ liệu thử nghiệm được tạo ra cho mỗi bài kiểm tra.
Tính năng này hoạt động cho đến khi chúng tôi thiết lập bộ bản sao mongodb. Bây giờ application.conf chứa cấu hình cho replicat này thiết lập

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

Khi FakeApplication sử dụng cấu hình mặc định các cuộc thử nghiệm thất bại vì host của replicaset không thể được tìm thấy. Tôi muốn có một cấu hình khác nhau cho các bài kiểm tra của tôi, về cơ bản loại bỏ các mục mongodb.default.replicaset. Nếu mongodb.default.replicaset là một Map [String, String] đơn giản sẽ dễ dàng như tôi có thể thêm nó vào additonalConfiguration nhưng khi tôi cố gắng làm điều đó nó thất bại vì kiểu giá trị dự kiến ​​không phải là một String mà là một đối tượng. Tôi cũng đã cố gắng cung cấp một tệp test.conf riêng biệt cho FakeApplication thông qua tham số đường dẫn.

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

Điều đó không có tác dụng vì không tải bất kỳ cấu hình nào.

Tôi rất cảm kích mọi trợ giúp. Cảm ơn.

Chris

Trả lời

3

Sự cố là cách chỉ định tệp test.conf khi chạy thử nghiệm tích hợp bằng FakeAppication của Play. Trong thử nghiệm tích hợp của tôi, tôi không thể gọi play -Dconfig.file=conf/test.conf.

Những gì tôi cố gắng làm điều này là:

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

Sử dụng path sẽ không làm việc ở đây, vì đây là con đường của FakeApplication bạn đang chạy (bạn có thể có một con đường khác nhau trong một số trường hợp).

Điều tôi muốn đề xuất trong trường hợp của bạn là chỉ định test.conf khi chạy Play cho chế độ thử nghiệm, ví dụ:

play -Dconfig.file=conf/test.conf 

Sau đó, test.conf sẽ được chọn. Sau đó bạn có thể có nó bao gồm bình thường application.conf và ghi đè lên chỉ các thiết lập mongo.

Có lẽ nó cũng có ý nghĩa để có "chế độ mục tiêu duy nhất" cách mặc định kết nối với mongodb trong application.conf và ghi đè cấu hình mongob để sử dụng bản sao chỉ trong cấu hình sản xuất.

10

Chúng tôi đã có một vấn đề tương tự tải cấu hình thêm cho thử nghiệm hội nhập của chúng tôi. Chúng tôi tìm thấy Populating bản đồ bằng tay để được tẻ nhạt vì vậy chúng tôi sử dụng phương pháp sau:

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

Tôi không biết nếu có một phương pháp tốt đẹp ở phía Scala của sự vật, chúng tôi đang làm tất cả các mã của chúng tôi trong java.

2

Đây là cách tôi đã thực hiện trong Play 2.3.x

  1. Xác định ứng dụng của tôi GlobalSettings trong một lớp học AppGlobal trong một gói (không phải là gói gốc)

    package configs 
    
    class AppGlobal extends GlobalSettings { 
        // Your application global settings 
        ??? 
    } 
    
  2. Xác định cài đặt toàn cầu ứng dụng như object Global extends AppGlobal được sử dụng ứng dụng của bạn.

  3. Trong lớp thử nghiệm, hãy xác định thử nghiệm toàn cầu. Cấu hình thử nghiệm được thêm vào ở cuối để ghi đè hoặc thêm vào cấu hình ứng dụng tổng thể:

    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. Tạo ứng dụng giả với trên TestGlobal

    FakeApplication(withGlobal = Some(TestGlobal)) 
    
1

Trong trường hợp của tôi, tôi có đơn giản tạo ra một lớp cơ sở mà tất cả các bài kiểm tra của tôi mở rộng. Ngay trước khi tạo FakeApplication, tôi xác định thuộc tính hệ thống config.resource để đặt cấu hình của ứng dụng. Sau đó, tôi đã có cấu trúc cấu hình của tôi như sau:

application.conf: contains no-env cấu hình cụ thể

test.conf: bao gồm application.conf và xác định cấu hình để chạy các đơn vị kiểm tra

env_local. conf: bao gồm application.conf và xác định cấu hình để chạy các ứng dụng cục bộ

env_prod.conf: như env_local.conf nhưng đối với sản xuất vv ...

Trong dự án của tôi, để thuận tiện, tôi đã soạn kịch bản local.sh chỉ cần chạy trình kích hoạt -Dconfig.resource = env_local.conf

@RunWith(classOf[JUnitRunner]) 
class ApplicationTest extends FunSuite with MockitoSugar { 
    System.setProperty("config.resource", "test.conf") 
    val app = Helpers.fakeApplication() 
} 
Các vấn đề liên quan