名前も知らないSEでしょう

この木なんの木気になる樹

Java

DBUnitでPostgreSQLのUUIDのテストをする

更新日:

自分で作りたいものを作る時間を増やすとアウトプットする時間がなくなるというジレンマ。
年末年始の棚卸しのおかげでReactで作っているアプリケーションはだいぶ見通しが良くなった。ネタもたくさんあるんだけどもなかなか筆が重いというか時間が足りないというか。

さて、久々にJava。ちょっとしたヘルプで調べた内容の備忘録。
表題の通りで、DBUnitでPostgreSQLのUUIDを利用したテーブルのテストをするときにぶつかった事象について。

特に考慮がされていない場合、NoSuchColumnExceptionが発生する問題について。同じ事象自体はStackOverflowにあるのでそちらを参照。解決策がまとまっている訳ではないので、それを簡単にまとめておきます。

特に何も意識せずにDBUnitを使っていると、DefaultDataTypeFactoryというものが自動的に割り当てられているはずです。しかし、PostgreSQLのUUIDのように、DBMSに依存した型を使っている場合はこれでは解決できないため、DBMSごとのDataTypeFactoryを適用する必要があります。
今回だと、PostgreSQLなので、PostgresqlDataTypeFactoryを利用します。

参考:http://dbunit.sourceforge.net/faq.html#typefactory

さて、これを適用するためには、上記リンクのようにIDatabaseConnectionの実装クラスのインスタンスに設定をする必要があるわけなのですが、IDatabaseTesterの実装クラスを用いている場合は少々工夫をする必要があります。

今回使っていたのはDataSourceDatabaseTesterでしたので、その実装を見てみます。
コメントは省略しています。

ハイライトした40-46行目がポイントです。
他のIDatabaseTesterの実装クラスも大体同様だと思いますが、getConnectionを呼び出すと、DatabaseConnectionのインスタンスを新たに生成して返却しています。

DatasourceDatabaseTesterを利用するコードのかなりざっくりとしたイメージとしては、こんな感じになると思います。

処理を追うと分かりますが、onSetupなどを呼び出すと、その先の処理でgetConnectionが呼び出される実装になっています。DataTypeFactoryは、getConnectionの戻り値であるIDatabaseConnectionのインスタンスに設定してあげる必要がありますが、getConnectionからは毎回新しいインスタンスが返却されるので、DataSourceDatabaseTesterのインスタンスからConfigを設定しても意味がなく、設定を効かせるためにはgetConnectionを拡張する必要があります。

ということで、数行の拡張でDataTypeFactoryを適応することができますね。
直接Connectionのインスタンスに触ることができるのであれば、そのまま設定すれば良いのでもっと簡単ですね。
今回は既存との関係で適応が難しかったので詳しく調べていませんが、Springを使っている場合だとまた別の設定方法があるのかもしれません。

追記:Twitterで@shiroikaさんに教えていただきましたが、この辺りのようです。
まさに後者の方は上記の拡張にたどり着く前に試していたやつでした。なるほどやはりそうなのね。

今回の例はPostgreSQLに閉じた拡張ですが、利用するDBに合わせて設定をできるようにテスト基盤を作っておくと良さそうですね。

これくらいのボリュームなら30分そこらで書けるから、軽いネタを作っていきたい。

-Java
-, ,

Copyright© この木なんの木気になる樹 , 2018 AllRights Reserved.