TDD测试时,需要访问Service层私有方法时,你应该这样办!

发表于:2020-7-22 10:26

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:樊亦凡    来源:掘金

  (私有方法?我偏要访问!)测试需要访问Service层私有方法时,你应该这样办!
  前言
  最近在写测试,TDD(测试驱动开发),然后写到了一个测试方法时,我还是照常调用了Service层,自己写的“public” 的 私有方法,
  (为什么这样说,因为这个方法只是为了提供了这个类的方法中某一个的方法使用,而创建的。没有任何复用可言,但是因为为了测试,所以写成了public,以便调用。)
  我一直很诧异,为什么一直要这样搞,缺少了代码的完整真实可读性,可能会让读代码的人第一反应造成不必要的误解,然后我就开始了接下来的探究。
  目标
  把代码改成 private 关键字修饰,不加任何静态修饰符或者单例修饰等等。保证代码完整真实性。
  代码
  AccountServicelmpl内代码
  不用在意方法内的内容
   private String subCardBinLastChar(String cardNo) {
  if (cardNo.length() <= CARD_BIN_PREFIX_MIN_LENGTH) {
  throw new ServiceException(ResultCode.BANK_NON_SUPPORT);
  }
  if (cardNo.length() > CARD_BIN_PREFIX_MAX_LENGTH) {
  return StringUtils.substring(cardNo, 0, CARD_BIN_PREFIX_MAX_LENGTH);
  }
  return StringUtils.substring(cardNo, 0, cardNo.length() - 1);
  }
  写了工具类用于调用这个一个参数的方法
   /**
  * 用于测试返回Service静态方法
  * @author FYF
  * @date Created in 9:40 2020/6/22
  */
  public class ExecutePrivateMethods {
  public static <T> Object ClassReflect(Class<T> TClass, String method) {
  Class cl = null;
  try {
  cl = TClass;
  Object Clazz = cl.newInstance();
  Method m1 = cl.getDeclaredMethod(method);
  m1.setAccessible(true);
  Object invoke = m1.invoke(Clazz);
  return invoke;
  } catch (Exception e) {
  throw new ServiceException(e.getMessage());
  }
  }
  //带一个参数
  public static <T> Object ClassReflect(Class<T> TClass, String method,Object obj) {
  Class cl = null;
  try {
  cl = TClass;
  Object Clazz = cl.newInstance();
  Method m1 = cl.getDeclaredMethod(method,obj.getClass());
  m1.setAccessible(true);
  Object invoke = m1.invoke(Clazz,obj);
  return invoke;
  } catch (Exception e) {
  throw new ServiceException(e.getMessage());
  }
  }
  }
  测试
   @ParameterizedTest
  @ValueSource(strings = {"12345678901234"})
  void testSubCardBinLengthForLong(String cardNo) {
  Object subCardBinLastChar = ExecutePrivateMethods.ClassReflect(AccountServiceImpl.class, "subCardBinLastChar", cardNo);
  String cardBin = subCardBinLastChar.toString();
  log.info("cardBin:{}", cardBin);
  assertEquals(AccountServiceImpl.CARD_BIN_PREFIX_MAX_LENGTH, cardBin.length());
  }
  测试结果:成功
  关键代码
   Class cl = null;
  try {
  cl = TClass.class(替换成你要调用的class);
  Object Clazz = cl.newInstance();
  Method m1 = cl.getDeclaredMethod("methonName"(方法名),String(参数类型).getClass);
  m1.setAccessible(true);
  Object invoke = m1.invoke(Clazz,"参数"(参数));
  return invoke;
  } catch (Exception e) {
  throw new ServiceException(e.getMessage());
  }
  }
  }
  总结
  用反射的机制去映射出一个类,然后去调用它的私有方法,因为反射可以把私有方法也映射出来。

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号