1. ホーム
  2. java

MongoDBを使ったユニットテスト

2023-09-22 21:12:22

質問

私が選択したデータベースはMongoDBです。私は、クライアントアプリケーションから実装の詳細を抽象化するために、データ層APIを書いています。

私は、TDD方式で自分のロジックをテストしています。各ユニットテストの前に @Before メソッドが呼び出されてデータベースのシングルトンが作成されます。その後、テストが完了すると @After メソッドが呼び出され、データベースを削除します。これはユニットテスト間の独立性を促進するのに役立ちます。

ほとんどすべてのユニットテスト、すなわち コンテキストクエリを実行する など、ほとんどすべてのユニットテストは、何らかの挿入ロジックが事前に発生することを必要とします。私の公開インターフェースは挿入メソッドを提供します。しかし、このメソッドを各単位テストの前置ロジックとして使用するのは正しくないように思えます。

本当に私は何らかのモッキングメカニズムが必要です。しかし、私はモッキングフレームワークについてあまり経験がなく、GoogleはMongoDBで使用できるモッキングフレームワークについて何も返さないようです。

このような状況で他の人はどうしているのでしょうか?つまり、データベースと相互作用するコードをどのようにユニットテストしているのでしょうか?

また、私の公開インターフェースは外部設定ファイルで定義されたデータベースに接続します。この接続を私のユニットテストに使用するのは間違っているように思えます。

どのように解決するのですか?

sbridgesがこの投稿で書いたように、データアクセスをロジックから抽象化する専用のサービス(リポジトリやDAOとも呼ばれることがあります)を用意しないのは悪い考えです。それから、DAO のモックを提供することによってロジックをテストできます。

私が行っている別のアプローチは、Mongoオブジェクトのモック(例えばPowerMockito)を作成し、適切な結果を返すというものです。 これは、ユニットテストでデータベースが動作するかどうかをテストする必要はなく、正しいクエリがデータベースに送信されたかどうかをテストする必要があるためです。

Mongo mongo = PowerMockito.mock(Mongo.class);
DB db = PowerMockito.mock(DB.class);
DBCollection dbCollection = PowerMockito.mock(DBCollection.class);

PowerMockito.when(mongo.getDB("foo")).thenReturn(db);
PowerMockito.when(db.getCollection("bar")).thenReturn(dbCollection);

MyService svc = new MyService(mongo); // Use some kind of dependency injection
svc.getObjectById(1);

PowerMockito.verify(dbCollection).findOne(new BasicDBObject("_id", 1));

というのも選択肢の一つでしょう。もちろん、モックの作成と適切なオブジェクトの返送は、上記の例としてコード化されているだけです。