状況
PhoenixFramework + Mongodbな環境でAPIのテストをしていたのだが、テストごとに必要なDBのcleanupがめんどくさい。最初はテストが少なかったので個別に書いていたが、だんだん漏れが出てきたので一括でできる方法を模索していた。とりあえず対応できたのでまとめてみた。
環境
Elixir 1.3.1
PhoenixFramework 1.2.0
Espec 0.8.28
EspecPhoenix 0.5.0
MongodbEcto 0.1.2
MongoDB 3.2.0
解決方法
spec_helper.exs
にEspec.configure
を設定し、config.finally
でMongoDBのcommandを実行し、collectionをdropする。
概要
EspecPhoenixのREADMEには、Ecto.Adapters.SQL.Sandbox.checkout/1
を使う例が書いてあるがMongoDBなので使えない。
なので、強引だが処理ごとにDBをdropする方法を実践してみた。
ESpec.configure fn(config) ->
config.before fn ->
end
config.finally fn(shared) ->
Mongo.Ecto.command(YourApp.Repo, listCollections: 1) # collectionの一覧を取得
|> get_in(["cursor", "firstBatch"])
|> Enum.each(fn(x) ->
if x["name"] != "categories" do
Mongo.Ecto.command(YourApp.Repo, drop: x["name"]) # collectionを1つずつdrop
end
end)
end
end
おまけ
RDBな環境(MySQL,PostgreSQLなど)だとEspecPhoenixの例が使えるので楽。
ESpec.configure fn(config) ->
config.before fn(_tags) ->
:ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo)
end
config.finally fn(_shared) ->
Ecto.Adapters.SQL.Sandbox.checkin(YourApp.Repo, [])
end
end
まとめ
今回の方法で今のところ上手くいっているが、テストが増えてくると実行時間も関わってくる。その時にどう対応しようか?というのが今後の悩み。
MongoDBのAdapterがEcto2.0に対応していないので、今後のPhoenixFramework + MongoDBの組み合わせはちょっと不安要素が大きいので要注意。
全てのcollectionをtruncateするfunctionがMongodbEctoの0.1.4に導入されているが、Ectoとの依存関係が上手く解決できずに導入できなかった。それが解決できればもっと楽にcleanup処理ができそう。