Home | History | Annotate | Download | only in injection
      1 /*
      2  * Copyright (c) 2007 Mockito contributors
      3  * This program is made available under the terms of the MIT License.
      4  */
      5 
      6 package org.mockito.internal.configuration.injection;
      7 
      8 import org.mockito.Mockito;
      9 import org.mockito.Spy;
     10 import org.mockito.exceptions.base.MockitoException;
     11 import org.mockito.internal.util.MockUtil;
     12 import org.mockito.internal.util.reflection.FieldReader;
     13 
     14 import java.lang.reflect.Field;
     15 import java.util.Set;
     16 
     17 import static org.mockito.Mockito.withSettings;
     18 import static org.mockito.internal.util.reflection.FieldSetter.setField;
     19 
     20 /**
     21  * Handler for field annotated with @InjectMocks and @Spy.
     22  *
     23  * <p>
     24  * The handler assumes that field initialization AND injection already happened.
     25  * So if the field is still null, then nothing will happen there.
     26  * </p>
     27  */
     28 public class SpyOnInjectedFieldsHandler extends MockInjectionStrategy {
     29 
     30     @Override
     31     protected boolean processInjection(Field field, Object fieldOwner, Set<Object> mockCandidates) {
     32         FieldReader fieldReader = new FieldReader(fieldOwner, field);
     33 
     34         // TODO refoctor : code duplicated in SpyAnnotationEngine
     35         if(!fieldReader.isNull() && field.isAnnotationPresent(Spy.class)) {
     36             try {
     37                 Object instance = fieldReader.read();
     38                 if (MockUtil.isMock(instance)) {
     39                     // A. instance has been spied earlier
     40                     // B. protect against multiple use of MockitoAnnotations.initMocks()
     41                     Mockito.reset(instance);
     42                 } else {
     43                     Object mock = Mockito.mock(instance.getClass(), withSettings()
     44 					    .spiedInstance(instance)
     45 					    .defaultAnswer(Mockito.CALLS_REAL_METHODS)
     46 					    .name(field.getName()));
     47 					setField(fieldOwner, field, mock);
     48                 }
     49             } catch (Exception e) {
     50                 throw new MockitoException("Problems initiating spied field " + field.getName(), e);
     51             }
     52         }
     53 
     54         return false;
     55     }
     56 }
     57