Moq を使用してリポジトリをモックしました。ただし、最近、リポジトリ インターフェイスのハードコードされたテスト実装を作成することを好むと言う人もいました。
各アプローチの長所と短所は何ですか?
編集:ファウラーへのリンクを含むリポジトリの意味を明確にしました。
Moq を使用してリポジトリをモックしました。ただし、最近、リポジトリ インターフェイスのハードコードされたテスト実装を作成することを好むと言う人もいました。
各アプローチの長所と短所は何ですか?
編集:ファウラーへのリンクを含むリポジトリの意味を明確にしました。
通常、リポジトリには 2 つのシナリオがあります。私は何かを求めてそれを得るか、何かを求めてそこにない.
リポジトリをモックしている場合、それはテスト対象のシステム (SUT) がリポジトリを使用していることを意味します。そのため、通常は、リポジトリからオブジェクトが渡されたときに SUT が正しく動作することをテストする必要があります。また、何かが返ってくると期待しているのに返ってこない場合や、返されるかどうかわからない場合の状況を適切に処理することもテストする必要があります。
統合テストを行っている場合は、ハードコーディングされたテスト ダブルで問題ありません。オブジェクトを保存してから、元に戻したいとします。しかし、これは SUT の動作だけでなく、2 つのオブジェクトの相互作用をテストしています。それらは2つの異なるものです。偽のリポジトリのコーディングを開始する場合は、それらの単体テストも必要です。そうしないと、テストされていないコードに基づいてコードの成功と失敗を判断することになります。
これが、モッキングとテスト ダブルに関する私の意見です。
SCNR:
「あなたは自分のことをリポジトリと呼んでいますか? もっと容量の大きいマッチ箱を見たことがあります!」
「リポジトリ」とはDAOを意味すると思います。そうでない場合、この回答は適用されません。
最近、私は DAO の「メモリ内」「モック」(またはテスト) 実装を作成しています。これは基本的に、モックのコンストラクターに渡されたデータ (リスト、マップなど) を操作します。このようにして、単体テスト クラスは、テストに必要なデータを自由に投入したり、データを変更したりできます。これにより、「メモリ内」DAO で動作するすべての単体テストを強制的に同じテスト データを使用するようにコーディングする必要がなくなります。
このアプローチで私が見た利点の 1 つは、テストに同じ DAO を使用する必要がある多数の単体テストがある場合 (たとえば、テスト対象のクラスに挿入するため)、すべての DAO を覚えておく必要がないことです。毎回のテスト データの詳細 (「モック」がハードコーディングされている場合と同様) - 単体テストはテスト データ自体を作成します。欠点として、これは各単体テストがテスト データの作成と接続に数行を費やさなければならないことを意味します。しかし、それは私にとって小さな欠点です。
コード例:
public interface UserDao {
User getUser(int userid);
User getUser(String login);
}
public class InMemoryUserDao implements UserDao {
private List users;
public InMemoryUserDao(List users) {
this.users = users;
}
public User getUser(int userid) {
for (Iterator it = users.iterator(); it.hasNext();) {
User user = (User) it.next();
if (userid == user.getId()) {
return user;
}
}
return null;
}
public User getUser(String login) {
for (Iterator it = users.iterator(); it.hasNext();) {
User user = (User) it.next();
if (login.equals(user.getLogin())) {
return user;
}
}
return null;
}
}