/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.test; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.test.util.ReflectionTestUtils; /** Utilities for working with spring bean proxies and mockito * */ public class TargetProxyHelper { @SuppressWarnings( { "unchecked" }) public static <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception { while ((AopUtils.isJdkDynamicProxy(proxy))) { return (T) getTargetObject(((Advised) proxy).getTargetSource().getTarget(), targetClass); } return (T) proxy; // expected to be cglib proxy then, which is simply a // specialized class } /** Inject a bean into a Spring proxy - for when we don't have a method to do so. * We can't inject our mock using @InjectMock and MockitoAnnotations.initMocks(this) due to spring proxies * So we'll do it manually * * @param target * @param fieldname * @param thingToInject */ public static void injectIntoProxy(Object target,String fieldname, Object thingToInject){ ReflectionTestUtils.setField(unwrapProxy(target), fieldname, thingToInject); } /** Extract the bean from a Spring proxy * Similar to getTargetObject but you don't need to know the implementing class * see https://github.com/mockito/mockito/issues/209 * also see https://groups.google.com/forum/#!topic/mockito/DmkyGhmCDtY * @param bean * @return the unwrapped bean */ public static Object unwrapProxy(Object bean) { if (AopUtils.isAopProxy(bean) && bean instanceof Advised) { Advised advised = (Advised) bean; try { bean = advised.getTargetSource().getTarget(); } catch (Exception e) { throw new RuntimeException(e); } } return bean; } }