• 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;
6 
7 import java.lang.reflect.Field;
8 import java.util.HashSet;
9 import java.util.Set;
10 import org.mockito.MockitoAnnotations;
11 import org.mockito.internal.configuration.injection.scanner.InjectMocksScanner;
12 import org.mockito.internal.configuration.injection.scanner.MockScanner;
13 import org.mockito.plugins.AnnotationEngine;
14 
15 import static org.mockito.internal.util.collections.Sets.newMockSafeHashSet;
16 
17 /**
18  * See {@link MockitoAnnotations}
19  */
20 public class InjectingAnnotationEngine implements AnnotationEngine, org.mockito.configuration.AnnotationEngine {
21     private final AnnotationEngine delegate = new IndependentAnnotationEngine();
22     private final AnnotationEngine spyAnnotationEngine = new SpyAnnotationEngine();
23 
24     /**
25      * Process the fields of the test instance and create Mocks, Spies, Captors and inject them on fields
26      * annotated @InjectMocks.
27      *
28      * <p>
29      * This code process the test class and the super classes.
30      * <ol>
31      * <li>First create Mocks, Spies, Captors.</li>
32      * <li>Then try to inject them.</li>
33      * </ol>
34      *
35      * @param clazz Not used
36      * @param testInstance The instance of the test, should not be null.
37      *
38      * @see org.mockito.plugins.AnnotationEngine#process(Class, Object)
39      */
process(Class<?> clazz, Object testInstance)40     public void process(Class<?> clazz, Object testInstance) {
41         processIndependentAnnotations(testInstance.getClass(), testInstance);
42         processInjectMocks(testInstance.getClass(), testInstance);
43     }
44 
processInjectMocks(final Class<?> clazz, final Object testInstance)45     private void processInjectMocks(final Class<?> clazz, final Object testInstance) {
46         Class<?> classContext = clazz;
47         while (classContext != Object.class) {
48             injectMocks(testInstance);
49             classContext = classContext.getSuperclass();
50         }
51     }
52 
processIndependentAnnotations(final Class<?> clazz, final Object testInstance)53     private void processIndependentAnnotations(final Class<?> clazz, final Object testInstance) {
54         Class<?> classContext = clazz;
55         while (classContext != Object.class) {
56             //this will create @Mocks, @Captors, etc:
57             delegate.process(classContext, testInstance);
58             //this will create @Spies:
59             spyAnnotationEngine.process(classContext, testInstance);
60 
61             classContext = classContext.getSuperclass();
62         }
63     }
64 
65 
66     /**
67      * Initializes mock/spies dependencies for objects annotated with
68      * &#064;InjectMocks for given testClassInstance.
69      * <p>
70      * See examples in javadoc for {@link MockitoAnnotations} class.
71      *
72      * @param testClassInstance
73      *            Test class, usually <code>this</code>
74      */
injectMocks(final Object testClassInstance)75     public void injectMocks(final Object testClassInstance) {
76         Class<?> clazz = testClassInstance.getClass();
77         Set<Field> mockDependentFields = new HashSet<Field>();
78         Set<Object> mocks = newMockSafeHashSet();
79 
80         while (clazz != Object.class) {
81             new InjectMocksScanner(clazz).addTo(mockDependentFields);
82             new MockScanner(testClassInstance, clazz).addPreparedMocks(mocks);
83             onInjection(testClassInstance, clazz, mockDependentFields, mocks);
84             clazz = clazz.getSuperclass();
85         }
86 
87         new DefaultInjectionEngine().injectMocksOnFields(mockDependentFields, mocks, testClassInstance);
88     }
89 
onInjection(Object testClassInstance, Class<?> clazz, Set<Field> mockDependentFields, Set<Object> mocks)90     protected void onInjection(Object testClassInstance, Class<?> clazz, Set<Field> mockDependentFields, Set<Object> mocks) {
91 
92     }
93 
94 }
95