• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.configuration.injection.scanner;
6 
7 import org.mockito.Mock;
8 import org.mockito.MockitoAnnotations;
9 import org.mockito.Spy;
10 import org.mockito.internal.util.MockUtil;
11 import org.mockito.internal.util.reflection.FieldReader;
12 
13 import java.lang.reflect.Field;
14 import java.util.Set;
15 
16 import static org.mockito.internal.util.collections.Sets.newMockSafeHashSet;
17 
18 /**
19  * Scan mocks, and prepare them if needed.
20  */
21 public class MockScanner {
22     private MockUtil mockUtil = new MockUtil();
23     private final Object instance;
24     private final Class<?> clazz;
25 
26     /**
27      * Creates a MockScanner.
28      *
29      * @param instance The test instance
30      * @param clazz    The class in the type hierarchy of this instance.
31      */
MockScanner(Object instance, Class<?> clazz)32     public MockScanner(Object instance, Class<?> clazz) {
33         this.instance = instance;
34         this.clazz = clazz;
35     }
36 
37     /**
38      * Add the scanned and prepared mock instance to the given collection.
39      *
40      * <p>
41      * The preparation of mocks consists only in defining a MockName if not already set.
42      * </p>
43      *
44      * @param mocks Set of mocks
45      */
addPreparedMocks(Set<Object> mocks)46     public void addPreparedMocks(Set<Object> mocks) {
47         mocks.addAll(scan());
48     }
49 
50     /**
51      * Scan and prepare mocks for the given <code>testClassInstance</code> and <code>clazz</code> in the type hierarchy.
52      *
53      * @return A prepared set of mock
54      */
scan()55     private Set<Object> scan() {
56         Set<Object> mocks = newMockSafeHashSet();
57         for (Field field : clazz.getDeclaredFields()) {
58             // mock or spies only
59             FieldReader fieldReader = new FieldReader(instance, field);
60 
61             Object mockInstance = preparedMock(fieldReader.read(), field);
62             if (mockInstance != null) {
63                 mocks.add(mockInstance);
64             }
65         }
66         return mocks;
67     }
68 
preparedMock(Object instance, Field field)69     private Object preparedMock(Object instance, Field field) {
70         if (isAnnotatedByMockOrSpy(field)) {
71             return instance;
72         } else if (isMockOrSpy(instance)) {
73             mockUtil.maybeRedefineMockName(instance, field.getName());
74             return instance;
75         }
76         return null;
77     }
78 
isAnnotatedByMockOrSpy(Field field)79     private boolean isAnnotatedByMockOrSpy(Field field) {
80         return null != field.getAnnotation(Spy.class)
81                 || null != field.getAnnotation(Mock.class)
82                 || null != field.getAnnotation(MockitoAnnotations.Mock.class);
83     }
84 
isMockOrSpy(Object instance)85     private boolean isMockOrSpy(Object instance) {
86         return mockUtil.isMock(instance)
87                 || mockUtil.isSpy(instance);
88     }
89 }
90