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