001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     dmetzler
018 */
019package org.nuxeo.runtime.mockito;
020
021import org.mockito.configuration.AnnotationEngine;
022import org.mockito.internal.configuration.InjectingAnnotationEngine;
023import org.mockito.internal.configuration.SpyAnnotationEngine;
024
025/**
026 * @since 5.7.8
027 */
028public class NuxeoInjectingAnnotationEngine extends InjectingAnnotationEngine {
029    private AnnotationEngine delegate = new NuxeoDefaultAnnotationEngine();
030
031    private AnnotationEngine spyAnnotationEngine = new SpyAnnotationEngine();
032
033    /**
034     * Process the fields of the test instance and create Mocks, Spies, Captors and inject them on fields annotated
035     * @InjectMocks.
036     * <p>
037     * This code process the test class and the super classes.
038     * <ol>
039     * <li>First create Mocks, Spies, Captors.</li>
040     * <li>Then try to inject them.</li>
041     * </ol>
042     *
043     * @param clazz Not used
044     * @param testInstance The instance of the test, should not be null.
045     * @see org.mockito.configuration.AnnotationEngine#process(Class, Object)
046     */
047    @Override
048    public void process(Class<?> clazz, Object testInstance) {
049        processIndependentAnnotations(testInstance.getClass(), testInstance);
050        processInjectMocks(testInstance.getClass(), testInstance);
051    }
052
053    private void processInjectMocks(final Class<?> clazz, final Object testInstance) { // NOSONAR
054        Class<?> classContext = clazz;
055        while (classContext != Object.class) {
056            injectMocks(testInstance);
057            classContext = classContext.getSuperclass();
058        }
059    }
060
061    private void processIndependentAnnotations(final Class<?> clazz, final Object testInstance) { // NOSONAR
062        Class<?> classContext = clazz;
063        while (classContext != Object.class) {
064            // this will create @Mocks, @Captors, etc:
065            delegate.process(classContext, testInstance);
066            // this will create @Spies:
067            spyAnnotationEngine.process(classContext, testInstance);
068
069            classContext = classContext.getSuperclass();
070        }
071    }
072
073}