All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mockito.internal.configuration.injection.ConstructorInjection Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2007 Mockito contributors
 * This program is made available under the terms of the MIT License.
 */

package org.mockito.internal.configuration.injection;

import org.mockito.exceptions.Reporter;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.reflection.FieldInitializationReport;
import org.mockito.internal.util.reflection.FieldInitializer;
import org.mockito.internal.util.reflection.FieldInitializer.ConstructorArgumentResolver;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Injection strategy based on constructor.
 *
 * 

* The strategy will search for the constructor with most parameters * and try to resolve mocks by type. *

* *
* TODO on missing mock type, shall it abandon or create "noname" mocks. * TODO and what if the arg type is not mockable. *
* *

* For now the algorithm tries to create anonymous mocks if an argument type is missing. * If not possible the algorithm abandon resolution. *

*/ public class ConstructorInjection extends MockInjectionStrategy { private ConstructorArgumentResolver argResolver; public ConstructorInjection() { } // visible for testing ConstructorInjection(ConstructorArgumentResolver argResolver) { this.argResolver = argResolver; } public boolean processInjection(Field field, Object fieldOwner, Set mockCandidates) { try { SimpleArgumentResolver simpleArgumentResolver = new SimpleArgumentResolver(mockCandidates); FieldInitializationReport report = new FieldInitializer(fieldOwner, field, simpleArgumentResolver).initialize(); return report.fieldWasInitializedUsingContructorArgs(); } catch (MockitoException e) { if(e.getCause() instanceof InvocationTargetException) { Throwable realCause = e.getCause().getCause(); new Reporter().fieldInitialisationThrewException(field, realCause); } // other causes should be fine return false; } } /** * Returns mocks that match the argument type, if not possible assigns null. */ static class SimpleArgumentResolver implements ConstructorArgumentResolver { final Set objects; public SimpleArgumentResolver(Set objects) { this.objects = objects; } public Object[] resolveTypeInstances(Class... argTypes) { List argumentInstances = new ArrayList(argTypes.length); for (Class argType : argTypes) { argumentInstances.add(objectThatIsAssignableFrom(argType)); } return argumentInstances.toArray(); } private Object objectThatIsAssignableFrom(Class argType) { for (Object object : objects) { if(argType.isAssignableFrom(object.getClass())) return object; } return null; } } }