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