データベース呼び出しに対して単体テストを作成していることに気付くのはごく普通のことですが、常に同じ問題が発生します。適切なクエリがデータベースに送信されているかどうかを検証するにはどうすればよいですか。
たとえば、次の形式でデータベースに最終更新を送信するこのクラスがあります。
update credential set password_hash = ?, password_crypt = ?, password_plain = ? where id = ?
password_plain
(これはパスワード移行ツールです。フィールドのセキュリティ問題を気にしないでください)
このクラスのテストクラスを作成し、データベースアクセスクラスをモックし(この場合はSpring JDBCTemplateを使用しています)、発行されたSQLをキャプチャしました。SQLを取得したら、次のチェックを行います。
String space = "\\s+";
String optSpace = "\\s*";
String something = ".+";
String optSomething = ".*";
sql = sql.toLowerCase();
assertTrue(sql.matches(optSpace + "update" + space + "credential" + space + "set" + space + something));
assertTrue(sql.matches(something + space + "set" + space + optSomething + "password_hash" + optSpace + "=" + optSpace + "\\?" + something + "where" + something));
assertTrue(sql.matches(something + space + "set" + space + optSomething + "password_crypt" + optSpace + "=" + optSpace + "\\?" + something + "where" + something));
assertTrue(sql.matches(something + space + "set" + space + optSomething + "password_plain" + optSpace + "=" + optSpace + "\\?" + something + "where" + something));
assertTrue(sql.matches(something + space + "where" + space + optSomething + "id" + optSpace + "=" + optSpace + "\\?" + optSomething));
これらのチェックにより、発行されたSQLに次のような更新の最も重要な部分が含まれているかどうかを実際に検証しています。
- 正しいテーブルが更新されています
- 3つのフィールドすべてが、パラメーターとして渡された値に更新されています
- はステートメントで
id
使用されており、その値はパラメーターです。where
発行されたクエリが上記の予想されるクエリであるかどうかを簡単に検証できますが、テストが制限されすぎて将来の変更ができなくなり、更新が正しい場合でも、クエリの一部が変更された場合は強制的に失敗します。テストは主に将来(ソフトウェアを変更していて、それに対してより安心が必要な場合)に使用されるように作成されており、現在では使用されないと思うので、このオプションを使用すると、テストは少し役に立たなくなります。
最後に、私の質問を宣言します。発行されたSQLを検証するためのより良いオプションはどれですか。
データベースを処理するクラスをテストするために、少量のデータで小さな組み込みデータベースを作成するプロジェクトがたくさんありますが、より純粋な単体テストの代替案を作成したいと思いました(それを呼び出すことができる場合)