Map<String,Widget>
プロパティを含む単純なPOJOがあります。
private Map<String, Widget> widgetCache = new HashMap<String, Widget>();
@Override
public Logger newWidget(String name, Widget widget) {
// First, print the contents of widgetCache in pretty print format.
Map<String, Widget> map = widgetCache;
List<String> keys = new ArrayList<String>(map.keySet());
System.out.println("Printing..." + keys.size());
for (String key: keys)
System.out.println(key + ": " + map.get(key).getName());
if(!widgetCache.containsKey(name)) {
System.err.println("I don't contain " + name);
widgetCache.put(name, widget);
}
return widgetCache.get(name);
}
Widget
非常に単純です。重複したをマップに挿入することはできません。Mockito(1.9.5)を使用してJUnitテストメソッドでこれをテストする場合:
CachingWidgetFactory fixture = new CachingWidgetFactory();
// By the way, I get errors if I try to make this next line:
// HashMap<String,Widget> mockMap = Mockito.mock(HashMap<String,Widget>.class);
// How do I enforce generics here when defining a mock?
HashMap mockMap = Mockito.mock(HashMap.class);
fixture.setLoggerCache(mockMap);
fixture.newWidget("Widget-A", new Widget("Widget-A"));
fixture.newWidget("Widget-A", new Widget("Widget-A"));
Mockito.verify(mockMap, Mockito.times(1))
.put(Mockito.anyString(), Mockito.<Logger>any());
次のJUnit出力でテストが失敗します。
org.mockito.exceptions.verification.TooManyActualInvocations:
hashMap.put(<any>, <any>);
Wanted 1 time:
そして、(STDOUT)コンソール出力には、次のように表示されます。
Printing...0
I don't contain Widget-A
Printing...0
I don't contain Widget-A
したがって、Mockitoが返しているモックは、2番目の(重複した)挿入を許可しているように見えます。ただし、MockitoをmockMap
完全に削除して、テストメソッドを次のようにすると、次のようになります。
CachingWidgetFactory fixture = new CachingWidgetFactory();
fixture.newWidget("Widget-A", new Widget("Widget-A"));
fixture.newWidget("Widget-A", new Widget("Widget-A"));
次に、コンソール出力で、次のようになります。
Printing...0
I don't contain Widget-A
Printing...1
これで、(モックされていない)コードが重複挿入を正しく防止しています。つまり、Mockitoが呼び出されるHashMap
たびに新しいものを返してnewWidget
いるようです。ここで何が起こっているのか、そしてその理由は?(そして、上記の一般的な問題について私を助けることができればボーナスポイント。)よろしくお願いします。