Package org.mockito.internal.configuration

Source Code of org.mockito.internal.configuration.DefaultAnnotationEngine

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

package org.mockito.internal.configuration;

import org.mockito.*;
import org.mockito.configuration.AnnotationEngine;
import org.mockito.exceptions.Reporter;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.reflection.FieldSetter;
import org.mockito.internal.util.reflection.GenericMaster;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
* Initializes fields annotated with @{@link org.mockito.Mock} or @{@link org.mockito.Captor}.
*
* <p>
* The {@link #process(Class, Object)} method implementation <strong>does not</strong> process super classes!
*
* @see {@link MockitoAnnotations}
*/
@SuppressWarnings("unchecked")
public class DefaultAnnotationEngine implements AnnotationEngine {

    /* (non-Javadoc)
    * @see org.mockito.AnnotationEngine#createMockFor(java.lang.annotation.Annotation, java.lang.reflect.Field)
    */
    @SuppressWarnings("deprecation")
    public Object createMockFor(Annotation annotation, Field field) {
        if (annotation instanceof Mock) {
            return processAnnotationOn((Mock) annotation, field);
        }
        if (annotation instanceof MockitoAnnotations.Mock) {
            return processAnnotationOn((MockitoAnnotations.Mock) annotation, field);
        }
        if (annotation instanceof Captor) {
            return processAnnotationOn((Captor) annotation, field);
        }       

        return null;
    }
   
    private Object processAnnotationOn(Mock annotation, Field field) {
        MockSettings mockSettings = Mockito.withSettings();
        if (annotation.extraInterfaces().length > 0) { // never null
            mockSettings.extraInterfaces(annotation.extraInterfaces());
        }
        if ("".equals(annotation.name())) {
            mockSettings.name(field.getName());
        } else {
            mockSettings.name(annotation.name());
        }

        // see @Mock answer default value
        mockSettings.defaultAnswer(annotation.answer().get());
        return Mockito.mock(field.getType(), mockSettings);
    }

    @SuppressWarnings("deprecation")
    private Object processAnnotationOn(org.mockito.MockitoAnnotations.Mock annotation, Field field) {
        return Mockito.mock(field.getType(), field.getName());
    }
   
    private Object processAnnotationOn(Captor annotation, Field field) {
        Class<?> type = field.getType();
        if (!ArgumentCaptor.class.isAssignableFrom(type)) {
            throw new MockitoException("@Captor field must be of the type ArgumentCaptor.\n" + "Field: '"
                    + field.getName() + "' has wrong type\n"
                    + "For info how to use @Captor annotations see examples in javadoc for MockitoAnnotations class.");
        }
        Class cls = new GenericMaster().getGenericType(field);       
        return ArgumentCaptor.forClass(cls);   
    }          

    public void process(Class<?> clazz, Object testInstance) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            boolean alreadyAssigned = false;
            for(Annotation annotation : field.getAnnotations()) {          
                Object mock = createMockFor(annotation, field);
                if (mock != null) {
                    throwIfAlreadyAssigned(field, alreadyAssigned);                   
                    alreadyAssigned = true;                   
                    try {
                        new FieldSetter(testInstance, field).set(mock);
                    } catch (Exception e) {
                        throw new MockitoException("Problems setting field " + field.getName() + " annotated with "
                                + annotation, e);
                    }
                }       
            }
        }
    }
   
    void throwIfAlreadyAssigned(Field field, boolean alreadyAssigned) {
        if (alreadyAssigned) {
            new Reporter().moreThanOneAnnotationNotAllowed(field.getName());
        }
    }
}
TOP

Related Classes of org.mockito.internal.configuration.DefaultAnnotationEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.