2015-10-28 7 views
11

Ich möchte mein Evolution Script am Anfang jeder Testdatei manuell ausführen. Ich arbeite mit Play! 2.4 und Slick 3.Wie man manuelle Entwicklungen in Tests mit Slick and Play anwendet! 2.4

Gemäß der Dokumentation, scheint der Weg zu gehen zu sein:

Evolutions.applyEvolutions(database) 

aber ich schaffe keine Instanz meiner Datenbank zu erhalten. Im documentationplay.api.db.Databases wird importiert, um eine Datenbankinstanz zu bekommen, aber wenn ich versuche, es zu importieren, ich diesen Fehler: object Databases is not a member of package play.api.db

Wie kann ich eine Instanz meiner Datenbank zu erhalten, um die Evolution Skript ausführen?

Edit: wie in den Kommentaren gefragt, hier ist die gesamte Codequelle den Fehler geben:

import models._ 
import org.scalatest.concurrent.ScalaFutures._ 
import org.scalatest.time.{Seconds, Span} 
import org.scalatestplus.play._ 
import play.api.db.evolutions.Evolutions 
import play.api.db.Databases 

class TestAddressModel extends PlaySpec with OneAppPerSuite { 
    lazy val appBuilder = new GuiceApplicationBuilder() 
    lazy val injector = appBuilder.injector() 
    lazy val dbConfProvider = injector.instanceOf[DatabaseConfigProvider] 

    def beforeAll() = { 
    //val database: Database = ??? 
    //Evolutions.applyEvolutions(database) 
    } 

    "test" must { 
    "test" in { } 
    } 
} 
+0

können Sie den Quellcode veröffentlichen, welche die verursacht Error? – kukido

+0

Die gleiche Frage wird hier gestellt: http://stackoverflow.com/questions/31884182/play-2-4-2-play-slick-1-0-0-how-do-i-apply-database-evolutions- to-a-slick-man – Simon

+0

Ich hatte Probleme mit der Antwort unten, die zuerst zu funktionieren schien, und fand eine andere Lösung, die ich hier referenziere anstatt zu kopieren: http://stackoverflow.com/questions/42368523/play-tests -mit-Datenbank-zu-viele-Verbindungen/42416309 # 42416309. – JulienD

Antwort

11

Schließlich fand ich diese Lösung. Ich spritze mit Guice:

lazy val appBuilder = new GuiceApplicationBuilder() 

lazy val injector = appBuilder.injector() 

lazy val databaseApi = injector.instanceOf[DBApi] //here is the important line 

(Sie haben play.api.db.DBApi zu importieren.)

Und in meinen Tests, das tue ich einfach die folgende (eigentlich verwende ich eine andere Datenbank für meine Tests):

override def beforeAll() = { 
    Evolutions.applyEvolutions(databaseApi.database("default")) 
} 

override def afterAll() = { 
    Evolutions.cleanupEvolutions(databaseApi.database("default")) 
} 
+0

Mit dieser Technik bekomme ich nach dem Schreiben von mehr Tests einen "Too many connections" Fehler: http://stackoverflow.com/questions/42368523/play-tests-with-database-too-many-connections?noredirect=1#comment71900106_42368523. Irgendeine Idee wo das Leck ist? – JulienD

2

Bedenkt man, dass man 2,4 Wiedergabe verwenden, wo Entwicklungen in einem separaten Modul verschoben wurden, haben Sie fügen Sie Ihren Projektabhängigkeiten evolutions hinzu.

libraryDependencies += evolutions 
+0

evolutions ist bereits in meiner build.sbt Datei hinzugefügt – Simon

0

ich die einfachste Weg finden Tests mit Evolutionen ausführen angewendet wird FakeApplication zu verwenden, und geben Sie die Verbindungsinformationen für den DB manuell .

def withDB[T](code: => T): T = 
    // Create application to run database evolutions 
    running(FakeApplication(additionalConfiguration = Map(
    "db.default.driver" -> "<my-driver-class>", 
    "db.default.url"  -> "<my-db-url>", 
    "db.default.user"  -> "<my-db>", 
    "db.default.password" -> "<my-password>", 
    "evolutionplugin"  -> "enabled" 
    ))) { 
    // Start a db session 
    withSession(code) 
    } 

es wie folgt verwendet:

"test" in withDB { } 

Diese Sie können zum Beispiel Ihre Unit-Tests für die Beschleunigung eines In-Memory-Datenbank zu verwenden.

Sie können auf die DB-Instanz als play.api.db.DB zugreifen, wenn Sie sie benötigen. Sie müssen auch import play.api.Play.current.

+0

Ich weiß, wie man autoEvolutions aktiviert, was ich tun möchte, ist das Evolutionsskript für jede Testdatei auszuführen, auch wenn es keine Änderungen gab (in der 1.sql Datei). Deshalb möchte ich eine Datenbankinstanz haben und sehe nicht, wo ich sie mit deinem Code haben kann. Außerdem habe ich bereits verschiedene Konfigurationen für meinen Test mit GuiceApplicationBuilder festgelegt. – Simon

+0

Warum beginnen Sie nicht mit einer leeren DB für jeden Test und wenden Sie alle Entwicklungen an? Andernfalls treten Probleme auf, wenn die Tests den DB nicht in den richtigen Zustand zurückversetzen. – jazmit

+0

Genau das möchte ich machen! ;) (Nicht mit einer In-Memory-Datenbank, aber ich denke nicht, dass es anders wäre.) – Simon

0

Verwenden Sie FakeApplication, um Ihre DB-Konfiguration zu lesen und eine DB-Instanz bereitzustellen.

def withDB[T](code: => T): T = 
    // Create application to run database evolutions 
    running(FakeApplication(additionalConfiguration = Map(
     "evolutionplugin" -> "disabled"))) { 
    import play.api.Play.current 
    val database = play.api.db.DB 
    Evolutions.applyEvolutions(database) 
    withSession(code) 
    Evolutions.cleanupEvolutions(database) 
    } 

es wie folgt verwendet:

"test" in withDB { } 
+2

Das Problem mit Ihrem Code ist, dass, da ich Slick verwende, ich eine Instanz meiner Datenbank mit play.api.db.DB bekommen kann – Simon

1

Um den Zugriff auf play.api.db.Databases haben, können Sie jdbc auf Ihre Abhängigkeiten müssen hinzufügen:

libraryDependencies += jdbc 

Ich hoffe, es hilft ein paar Leute vorbeikommen.

EDIT: Der Code würde dann wie folgt aussehen:

import play.api.db.Databases 

val database = Databases(
    driver = "com.mysql.jdbc.Driver", 
    url = "jdbc:mysql://localhost/test", 
    name = "mydatabase", 
    config = Map(
    "user" -> "test", 
    "password" -> "secret" 
) 
) 

Sie nun eine Instanz der DB hat, und kann Abfragen auf es ausführen:

val statement = database.getConnection().createStatement() 
val resultSet = statement.executeQuery("some_sql_query") 

Sie können mehr von dem sehen docs

EDIT: Tippfehler

+0

Danke, aber es ist nicht die Frage ... – Simon

+0

Meine Antwort war nicht vollständig genug, denke ich. Wenn Sie diese 'play.api.db.Database' haben, können Sie Ihr Datenbank-Objekt wie in den Dokumenten erstellen, und dort haben Sie Ihre Datenbankinstanz, auf der Sie' Evolutions.applyEvolutions (database) '' –

+0

verwenden können Sie haben Ihre Datenbankinstanz anders als ich es in der Antwort erhalten habe? – Simon