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