Home | History | Annotate | Download | only in configuration
      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      */
     40     public void process(Class<?> clazz, Object testInstance) {
     41         processIndependentAnnotations(testInstance.getClass(), testInstance);
     42         processInjectMocks(testInstance.getClass(), testInstance);
     43     }
     44 
     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 
     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      */
     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 
     90     protected void onInjection(Object testClassInstance, Class<?> clazz, Set<Field> mockDependentFields, Set<Object> mocks) {
     91 
     92     }
     93 
     94 }
     95