org.mockito.internal.configuration.injection.PropertyAndSetterInjection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mockito-core Show documentation
Show all versions of mockito-core Show documentation
Mockito mock objects library core API and implementation
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.configuration.injection;
import static org.mockito.internal.exceptions.Reporter.cannotInitializeForInjectMocksAnnotation;
import static org.mockito.internal.exceptions.Reporter.fieldInitialisationThrewException;
import static org.mockito.internal.util.collections.Sets.newMockSafeHashSet;
import static org.mockito.internal.util.reflection.SuperTypesLastSorter.sortSuperTypesLast;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.configuration.injection.filter.MockCandidateFilter;
import org.mockito.internal.configuration.injection.filter.NameBasedCandidateFilter;
import org.mockito.internal.configuration.injection.filter.TerminalMockCandidateFilter;
import org.mockito.internal.configuration.injection.filter.TypeBasedCandidateFilter;
import org.mockito.internal.util.reflection.FieldInitializationReport;
import org.mockito.internal.util.reflection.FieldInitializer;
/**
* Inject mocks using first setters then fields, if no setters available.
*
*
* Algorithm :
* for each field annotated by @InjectMocks
*
* - initialize field annotated by @InjectMocks
*
- for each fields of a class in @InjectMocks type hierarchy
*
* - make a copy of mock candidates
*
- order fields from sub-type to super-type, then by field name
*
- for the list of fields in a class try two passes of :
*
* - find mock candidate by type
*
- if more than *one* candidate find mock candidate on name
*
- if one mock candidate then
*
* - set mock by property setter if possible
*
- else set mock by field injection
*
* - remove mock from mocks copy (mocks are just injected once in a class)
*
- remove injected field from list of class fields
*
* - else don't fail, user will then provide dependencies
*
*
*
*
*
* Note: If the field needing injection is not initialized, the strategy tries
* to create one using a no-arg constructor of the field type.
*
*/
public class PropertyAndSetterInjection extends MockInjectionStrategy {
private final MockCandidateFilter mockCandidateFilter =
new TypeBasedCandidateFilter(
new NameBasedCandidateFilter(new TerminalMockCandidateFilter()));
@Override
public boolean processInjection(
Field injectMocksField, Object injectMocksFieldOwner, Set