読者です 読者をやめる 読者になる 読者になる

Play framework 2でinMemory以外のDBでテストを行う

下記を買って、Play Framework 2を使っています。

テストを書こうと思って、Chapter7のFakeAppをコピーしてやってみました。

で、実行してみたところ、PostGIS関連の特殊カラム関係でエラーになってしまいました。

そのため、inMemoryDatabaseをやめて、実際のPostgreSQLを利用しようと思って、ハマりまくりました。

あと、GlobalSettingsを継承したクラスでDBアクセスしてたので、さらにわけのわからんエラーが出ました。

まず、startAppでFakeApplicationを作成。

@BeforeClass
public static void startApp() throws IOException {
    Map<String, Object> map = new HashMap<>();
    map.put("db.default.url",
            "jdbc:postgresql://127.0.0.1:5432/sample_db");
    map.put("db.default.user", "web_dev");
    map.put("db.default.password", "password");

    app = fakeApplication(map, new GlobalSettings());
    start(app);
    String evolutionContent = FileUtils.readFileToString(app
            .getWrappedApplication().getFile(
                    "conf/evolutions/default/1.sql"));
    String[] splitEvolutionContent = evolutionContent.split("# --- !Ups");
    String[] upsDowns = splitEvolutionContent[1].split("# --- !Downs");
    createDdl = upsDowns[0];
    dropDdl = upsDowns[1];
}

これで、リクエスト時のDBはPostgreSQLに向く。

あと、DDL文を実行し、テーブルを作成。

@Before
public void createCleanDb() {
    final DataSourceConfig dataSourceConfig = new DataSourceConfig(){{
        setDriver("org.postgresql.Driver");
        setUrl("jdbc:postgresql://127.0.0.1:5432/sample_db");
        setUsername("web_dev");
        setPassword("password");
    }};
    ServerConfig serverConfig = new ServerConfig(){{
        setName("test");
        setDataSourceConfig(dataSourceConfig);
        setRegister(false);
        setDdlRun(false);
        setDdlGenerate(false);
        setDefaultServer(false);
    }};

    // transactionで囲み、commitしないと反映されなかった
    EbeanServer ebeanServer = EbeanServerFactory.create(serverConfig);
    ebeanServer.beginTransaction();
    ebeanServer.execute(ebeanServer.createCallableSql(dropDdl));
    ebeanServer.execute(ebeanServer.createCallableSql("commit;"));
    ebeanServer.execute(ebeanServer.createCallableSql(createDdl));
    ebeanServer.execute(ebeanServer.createCallableSql("commit;"));
    ebeanServer.commitTransaction();
}

DROP文→CREATE文をとりあえず投げておけばOKかと思ったら、コメントで書いてあるように、transactionで囲んでそれぞれcommitしないとうまく動かなかった。

もっと普通のやり方があってもいいと思うけど、調べててもなかなか出てこなくて困った。

Play Framework自体あんまり情報が見つからないイメージ。しかも、バージョンごとに結構違ってて困る。

公式を探すしか無い印象。

テストのやり方とか、Ruby on Railsほど整ってない感じ。

とはいえ、Rubyの開発者よりはJavaの開発者の方が調達しやすいとかの関係で、Javaの案件もやらざるを得ない感じ。 (PHPは個人的に好きでない。。。)

Springもそのうちまともにやってみたいとは思うけど、「Play」だったり「Spring」だったり、なんでこんなにググラビリティの悪いものが多いんだろう。。。