单元测试被spring管理的类(如service实现类)中的私有方法

目标

ServiceImpl类中有一个私有方法MethodA,而ServiceImpl是被spring管理的,该类中有一些用@Autowired注入的依赖项,因此不能直接new来创建它的实例,需要通过spring来创建它的实例,那么该怎么测试该私有方法呢?

方案

测试类

public class Test {
  @Autowired
  ServiceImpl serviceImpl;

  @Test
  public void test() throws Exception {
  Class<?> clazz = Class.forName("ServiceImpl");
  Method method = clazz.getDeclaredMethod("MethodA");
  method.setAccessible(true);
  Object target = ReflectionUtil.getTarget(serviceImpl);
  // 注意,这里不能直接用serviceImpl,因为它已经被spring管理,
  // 变成serviceImpl真实实例的代理类,而代理类中并没有私有方法,所以需要先获取它的真实实例
  method.invoke(target);
  }
}

获取spring 代理对象的真实实例的工具类
适用于两种动态代理情况:jdk和cglib

public class ReflectionUtil {
  /**
   * 获取spring 代理对象的真实实例
   * @param proxy 代理对象
   * @return
   * @throws Exception
   */
  public static Object getTarget(Object proxy) throws Exception {
    if(!AopUtils.isAopProxy(proxy)) {
      return proxy;//不是代理对象
    }

    if(AopUtils.isJdkDynamicProxy(proxy)) {
      return getJdkDynamicProxyTargetObject(proxy);
    } else { //cglib
      return getCglibProxyTargetObject(proxy);
    }
  }

  private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
    Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
    h.setAccessible(true);
    Object dynamicAdvisedInterceptor = h.get(proxy);
    Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
    advised.setAccessible(true);
    Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
    return target;
  }

  private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
    Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
    h.setAccessible(true);
    AopProxy aopProxy = (AopProxy) h.get(proxy);
    Field advised = aopProxy.getClass().getDeclaredField("advised");
    advised.setAccessible(true);
    Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
    return target;
  }
}

参考

https://www.cnblogs.com/sweetchildomine/p/5864296.html

猜你喜欢

转载自blog.csdn.net/weixin_43221845/article/details/84851133
今日推荐