2015-11-29 24 views
5

Tôi đã ứng dụng CRUD đơn giản được xây dựng với Scala Play 2.4.3Play-slick 1.1.0 (slick 3.1.0) sử dụng cơ sở dữ liệu MySQL để lưu trữ liên tục.Thử nghiệm ứng dụng Play + Slick

Tôi đã cố gắng để tạo ra các bài kiểm tra cho ứng dụng của tôi và tôi thấy 2 lựa chọn chính:

  • chế giễu truy cập cơ sở dữ liệu, mà như xa như tôi đã nhìn thấy, đòi hỏi phải có một số mã thay đổi
  • làm các xét nghiệm sử dụng một cơ sở dữ liệu thay thế (có lẽ, trong bộ nhớ H2).

Cách tiếp cận tốt nhất (thuận lợi và giải pháp) là gì?

Tôi thích phương pháp thứ hai, nhưng tôi đang tìm một số khó khăn trong việc thiết lập các thử nghiệm.

Tôi cần làm gì? Trước tiên, tôi nghĩ rằng tôi cần phải làm các xét nghiệm chạy với một FakeApplication, phải không? Tôi có cần bất kỳ phụ thuộc sbt nào để có thể làm điều đó không?

Sau đó, làm cách nào để chỉ định sử dụng cơ sở dữ liệu H2?

Trả lời

3

giải pháp của tôi là thêm step(Play.start(fakeApp)) vào đầu mỗi thông số kỹ thuật và step(Play.stop(fakeApp)) vào cuối mỗi thông số kỹ thuật.

Ngoài ra:

def fakeApp: FakeApplication = { 
FakeApplication(additionalConfiguration = 
    Map(
    "slick.dbs.default.driver" -> "slick.driver.H2Driver$", 
    "slick.dbs.default.db.driver" -> "org.h2.Driver", 
    "slick.dbs.default.db.url" -> "jdbc:h2:mem:play" 
)) 

}

này là cần thiết bởi vì tôi đang sử dụng play-slick, đòi hỏi cấu hình như:

slick.dbs.default.driver = "slick.driver.MySQLDriver$" 
slick.dbs.default.db.driver = "com.mysql.jdbc.Driver" 
slick.dbs.default.db.url = "jdbc:mysql://localhost/database" 
slick.dbs.default.db.user = "user" 
slick.dbs.default.db.password = "password" 

biết thêm về docs

+1

'Bước' này là gì? Từ khóa không dễ tìm kiếm. – JulienD

+0

Rất có thể chức năng từ specs2, cho phép bạn chạy những thứ nhất định trước và/hoặc sau khi kiểm tra. Tương tự như những gì bạn sẽ sử dụng một 'beforeAll' /' afterAll' cho. – rethab

5

tôi đã có cuộc đấu tranh đó và tôi đã đưa ra một giải pháp như thế này (sử dụng cách tiếp cận thứ hai):

Tạo một bối cảnh cho DAO để sử dụng:

trait BaseContext{ 

    def dbName: String 

    val dbConfig = DatabaseConfigProvider.get[JdbcProfile](dbName) 
    val db = dbConfig.db 
    val profile = dbConfig.driver 
    val tables = new Tables { // this is generated by Schema Code Generator 
    override val profile: JdbcProfile = dbConfig.driver 
    } 
} 

@Singleton 
class AppContext extends BaseContext{ 
    def dbName = "mysql" // name in your conf right after "slick.dbs" 
} 

@Singleton 
class TestingContext extends BaseContext{ 
    def dbName = "h2" 
} 

Sau đó tạo một module để ràng buộc tiêm, và đừng quên để kích hoạt nó trong conf sử dụng play.modules.enabled += "your.Module":

class ContextModule(environment: Environment, configuration: Configuration) extends AbstractModule { 

    override def configure(): Unit = { 
    if (configuration.getString("app.mode").contains("test")) { 
     bind(classOf[BaseContext]) 
      .to(classOf[TestingContext]) 
    } else { 
     bind(classOf[BaseContext]) 
      .to(classOf[AppContext]) 
    } 
    } 
} 

và tiêm nó vào mỗi DAO bạn đã tạo:

class SomeDAO @Inject()(context: BaseContext){ 

    val dbConfig = context.dbConfig 
    val db = context.db 
    val tables = context.tables 
    import tables.profile.api._ 

    def otherStuff.... 
    // you can call db.run(...), tables.WhateverYourTableIs, tables.TableRowCaseClass, ... 
} 

Và bước cuối cùng, tệp cấu hình của bạn. Trong trường hợp của tôi, tôi đã sử dụng app.mode để đánh dấu môi trường và tôi sử dụng riêng biệt .conf cho môi trường khác nhau. Nguyên nhân, trong những conf bạn phải có cấu hình DB chính xác. Đây là mẫu:

app.mode = "test" 

# Database configuration 
slick.dbs = { 
    # for unit test 
    h2 { 
    driver = "slick.driver.H2Driver$" 
    db = { 
     url = "jdbc:h2:mem:test;MODE=MYSQL" 
     driver = "org.h2.Driver" 
     keepAliveConnection = true 
    } 
    } 
} 

Tôi khá chắc chắn giải pháp của tôi không phải là một thanh lịch, nhưng nó cung cấp hàng hóa. :) Bất kỳ giải pháp nào tốt hơn đều được hoan nghênh!

+0

Hóa ra Typesafe có một dự án thể hiện chính xác điều này. https: // github.com/typesafehub/activator-slick-multidb –

+0

Tôi hoàn toàn nhận thức được ví dụ đó và nó đã cho tôi một số gợi ý. Tuy nhiên, điều đó không đáp ứng được kỳ vọng của tôi 100%. – noru

+0

Bạn đã bỏ lỡ điều gì? Trong nhánh mới nhất, 3.1, họ có những gì bạn hiển thị ở trên và sau đó là một số. –

Các vấn đề liên quan