2017-02-20 5 views
0

次のようにコードを整理しテストする方法については概念的に疑問があります。補助メソッドの呼び出しは、クラスのすべてのパブリックメソッドの最初の命令です。私の考えは、コードをきれいにし、テスト可能にすることです。このコードを整理してテストするにはどうすればよいですか?

このコードは、クラス "キャッシュ"によってこれを説明しようとする例です。このクラスには、オプションのプレフィックスがあり、キャッシュ内のすべてのキーに適用されます(設定されている場合)。

import java.util.HashMap; 


public class Cache { 
    private HashMap<String, Integer> inMemoryCache; 
    private String prefix; 


    public Cache() { 
     this.inMemoryCache = new HashMap<String, Integer>(); 
     prefix = null; 
    } 

    public void setPrefix(String prefix) { 
     this.prefix = prefix; 
    } 

    public int getValue(String key) throws NullPointerException { 
     String prefixedKey = applyPrefixOrDefault(key); 
     return inMemoryCache.get(prefixedKey); 
    } 

    public void setValue(String key, int value) { 
     String prefixedKey = applyPrefixOrDefault(key); 
     inMemoryCache.put(prefixedKey, value); 
    } 

    public boolean isCached(String key) { 
     String prefixedKey = applyPrefixOrDefault(key); 
     return inMemoryCache.containsKey(prefixedKey); 
    } 

    private String applyPrefixOrDefault(String key) { 
     if (prefix == null) { 
      return key; 
     } else { 
      return prefix + key; 
     } 
    } 


    public static void main (String[] arg) { 
     Cache cache = new Cache(); 
     cache.setPrefix("global:"); 
     cache.setValue("id", 4); 
     int value = cache.getValue("id"); 
     System.out.println(value); 
    } 
} 

このコードは私に二つの質問を提起:

  1. 私は、内部ハッシュテーブルにアクセスする多くの方法を持っていた場合、それは一つのクラスでのキャッシュとの行動の行動右別々のだろう他のプレフィックスは?

  2. これをテストする最もクリーンな方法は何でしょうか? getValue、setValueおよびisCachedをテストするには、プレフィックスを考慮しない場合は単純です。接頭辞では、キャッシュの正しい内部動作と、すべてのメソッドがデータにアクセスする前にapplyPrefixOrDefaultを呼び出すことをテストする必要があるという2つのことをテストする必要があります。

これは一般的な使用例であり、これを整理するためのデザインパターンが必要であると確信しています。何か案が?

答えて

1

ここで私が見逃しているのは、キャッシュの状態を設定できるコンストラクタです。次のようにだから私は1を追加します。

public Cache() { 
    this(null, new HashMap<String, Integer>()); 
} 

public Cache(String prefix, Map<String, Integer> cache) { 
    this.prefix = prefix; 
    this.inMemoryCache = cache; 
} 

をこの新しいコンストラクタを使用すると、すべての可能なキャッシュ状態のためのテストケースを記述することができるはずです。また、applyPrefixOrDefaultメソッドの可視性をprotectedまたはpackageに変更して、テストコードがそのメソッドにアクセスできるようにします。例えば、GetValueメソッドをテストするために、私は書くでしょう:

public class EmptyCacheTests { 

    private final Map<String, Integer> memory; 
    private final String prefix; 
    private final Cache cache; 

    public EmptyCacheTests() { 
     this.memory = new HasMap<String, Integer>(); 
     this.prefix = "foo"; 
     this.cache = new Cache(prefix, memory); 
    } 

    public void testGetValue() { 
     String key = this.cache.applyPrefixOrDefault("bar") 
     this.memory.put(key, 50); 
     result = this.cache.getValue("bar"); 
     assertEquals(50, result, "The value retrieved is wrong!"); 
    } 
} 

ここでのポイント、それは我々は、その後、さまざまなものに対してテストできるようにテストは、キャッシュの内部状態を設定できるようにします。

+0

もし私が多くのメソッド(例えば10-20のメソッド)を持っていたら、別のクラスの接頭辞の振る舞いを分けることを考えますか、接頭辞と接頭辞なしですべてのテストケースを複製しますか? – Garet

+0

はい、プレフィックスの有無にかかわらずテストする場合は、プレフィックス計算を別のクラスに分けて、可能なすべてのテストケースを列挙するのではなく、コンポジションでテストをビルドできるようにすることができます。 – Franck

+0

これについて考えると、 'prefix'属性はキャッシュに関連するのではなく、キーの計算/変換に関連しています。したがって、この接頭辞をカプセル化し、 'applyPrefixOrDefault'に似た' transformKey'メソッドを公開するKeyBuilderオブジェクトを作成します。次に、テストで定義できるように、KeyBuilderオブジェクトをキャッシュのコンストラクタに挿入することができます。 – Franck

関連する問題