package org.needle4j.mock; import static org.needle4j.common.Preconditions.checkArgument; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import org.mockito.Mockito; import org.needle4j.reflection.ReflectionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Mockito specific {@link MockProvider} implementation. For more details, see * the Mockito documentation. */ public class MockitoProvider implements MockProvider, SpyProvider { static { // fail fast if Mockito is not available. try { Class.forName("org.mockito.Mockito"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } private static final Logger LOG = LoggerFactory.getLogger(MockitoProvider.class); public static final String SPY_ANNOTATION_FQN = "org.mockito.Spy"; private final Class<? extends Annotation> spyAnnotation = (Class<? extends Annotation>) ReflectionUtil.forName(SPY_ANNOTATION_FQN); /** * {@inheritDoc} Skipping creation, if the type is final or primitive. * * @return the mock object or null, if the type is final or primitive. */ @Override public <T> T createMockComponent(final Class<T> type) { if (isFinalOrPrimitive(type)) { LOG.warn("Skipping creation of a mock : {} as it is final or primitive type.", type.getSimpleName()); return null; } return Mockito.mock(type); } /** * {@inheritDoc} Skipping creation, if the type is final or primitive. * * @return the mock object or null, if the type is final or primitive. */ @Override public <T> T createSpyComponent(final T instance) { checkArgument(instance != null, "instance must not be null!"); if (isFinalOrPrimitive(instance.getClass())) { LOG.warn("Skipping creation of a spy : {} as it is final or primitive type.", instance.getClass() .getSimpleName()); return null; } return Mockito.spy(instance); } /** * @param type * @return <code>true</code> if type is final or primitive, * <code>false</code> else. */ private boolean isFinalOrPrimitive(final Class<?> type) { return Modifier.isFinal(type.getModifiers()) || type.isPrimitive(); } @Override public Class<? extends Annotation> getSpyAnnotation() { return spyAnnotation; } @Override public boolean isSpyRequested(final Field field) { checkArgument(field != null, "field must not be null!"); return spyAnnotation != null && field.isAnnotationPresent(spyAnnotation); } }