1/* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6package org.mockito.internal.stubbing.defaultanswers; 7 8import org.mockito.internal.util.MockUtil; 9import org.mockito.internal.util.ObjectMethodsGuru; 10import org.mockito.internal.util.Primitives; 11import org.mockito.invocation.InvocationOnMock; 12import org.mockito.mock.MockName; 13import org.mockito.stubbing.Answer; 14 15import java.io.Serializable; 16import java.util.ArrayList; 17import java.util.Collection; 18import java.util.HashMap; 19import java.util.HashSet; 20import java.util.LinkedHashMap; 21import java.util.LinkedHashSet; 22import java.util.LinkedList; 23import java.util.List; 24import java.util.Map; 25import java.util.Set; 26import java.util.SortedMap; 27import java.util.SortedSet; 28import java.util.TreeMap; 29import java.util.TreeSet; 30 31/** 32 * Default answer of every Mockito mock. 33 * <ul> 34 * <li> 35 * Returns appropriate primitive for primitive-returning methods 36 * </li> 37 * <li> 38 * Returns consistent values for primitive wrapper classes (e.g. int-returning method retuns 0 <b>and</b> Integer-returning method returns 0, too) 39 * </li> 40 * <li> 41 * Returns empty collection for collection-returning methods (works for most commonly used collection types) 42 * </li> 43 * <li> 44 * Returns description of mock for toString() method 45 * </li> 46 * <li> 47 * Returns non-zero for Comparable#compareTo(T other) method (see issue 184) 48 * </li> 49 * <li> 50 * Returns null for everything else 51 * </li> 52 * </ul> 53 */ 54public class ReturnsEmptyValues implements Answer<Object>, Serializable { 55 56 private static final long serialVersionUID = 1998191268711234347L; 57 ObjectMethodsGuru methodsGuru = new ObjectMethodsGuru(); 58 MockUtil mockUtil = new MockUtil(); 59 60 /* (non-Javadoc) 61 * @see org.mockito.stubbing.Answer#answer(org.mockito.invocation.InvocationOnMock) 62 */ 63 public Object answer(InvocationOnMock invocation) { 64 if (methodsGuru.isToString(invocation.getMethod())) { 65 Object mock = invocation.getMock(); 66 MockName name = mockUtil.getMockName(mock); 67 if (name.isDefault()) { 68 return "Mock for " + mockUtil.getMockSettings(mock).getTypeToMock().getSimpleName() + ", hashCode: " + mock.hashCode(); 69 } else { 70 return name.toString(); 71 } 72 } else if (methodsGuru.isCompareToMethod(invocation.getMethod())) { 73 //see issue 184. 74 //mocks by default should not return 0 for compareTo because they are not the same. Hence we return 1 (anything but 0 is good). 75 //Only for compareTo() method by the Comparable interface 76 return 1; 77 } 78 79 Class<?> returnType = invocation.getMethod().getReturnType(); 80 return returnValueFor(returnType); 81 } 82 83 Object returnValueFor(Class<?> type) { 84 if (Primitives.isPrimitiveOrWrapper(type)) { 85 return Primitives.defaultValueForPrimitiveOrWrapper(type); 86 //new instances are used instead of Collections.emptyList(), etc. 87 //to avoid UnsupportedOperationException if code under test modifies returned collection 88 } else if (type == Collection.class) { 89 return new LinkedList<Object>(); 90 } else if (type == Set.class) { 91 return new HashSet<Object>(); 92 } else if (type == HashSet.class) { 93 return new HashSet<Object>(); 94 } else if (type == SortedSet.class) { 95 return new TreeSet<Object>(); 96 } else if (type == TreeSet.class) { 97 return new TreeSet<Object>(); 98 } else if (type == LinkedHashSet.class) { 99 return new LinkedHashSet<Object>(); 100 } else if (type == List.class) { 101 return new LinkedList<Object>(); 102 } else if (type == LinkedList.class) { 103 return new LinkedList<Object>(); 104 } else if (type == ArrayList.class) { 105 return new ArrayList<Object>(); 106 } else if (type == Map.class) { 107 return new HashMap<Object, Object>(); 108 } else if (type == HashMap.class) { 109 return new HashMap<Object, Object>(); 110 } else if (type == SortedMap.class) { 111 return new TreeMap<Object, Object>(); 112 } else if (type == TreeMap.class) { 113 return new TreeMap<Object, Object>(); 114 } else if (type == LinkedHashMap.class) { 115 return new LinkedHashMap<Object, Object>(); 116 } 117 // TODO return empty Iterable ; see issue 175 118 119 //Let's not care about the rest of collections. 120 return null; 121 } 122 123}