51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1319|回复: 1
打印 上一主题 下一主题

[转贴] 单元测试工具类ReflectionTestUtils

[复制链接]
  • TA的每日心情
    无聊
    3 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-1-25 15:39:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    前言
      在写单元测试时,是否经常遇到要测试的目标类中有很多私有注入的变量呢?然而我们经常并没有报漏此私有属性的getter and setter,因为这些私有属性的注入可能是通过配置文件,或者其他渠道,是在程序启动时根据环境不同或者其他因素来决定的,所以当我们测试的时候,就需要通过为该属性设置不同的值而来测试各种分支case,但是前面已经说了一般这种变量都是私有变量,如果说专门为了测试而将修饰符改为public/protected 那未免过于暴力....
      于是乎,大家常见的做法可能就是写一堆反射去修改,如果只有一处地方还好,但是如果需要测试此种场景的过多,那是不是写都写烦了,所以ReflectionTestUtils解放你的双手。
      用法
      首先搞一个service来辅助:
    1.  public class TestServiceImpl {
    2.       private String configId = "11111";
    3.       public String getConfigId() {
    4.           return configId;
    5.       }
    6.   }
    复制代码
    新建一个测试类:
    1. class TestServiceImplTest {
    2.       private TestServiceImpl testService = new TestServiceImpl();
    3.       @Test
    4.       void getConfigId() {
    5.           System.out.println("修改前:" + testService.getConfigId());
    6.           ReflectionTestUtils.setField(testService,"configId","2222");
    7.           System.out.println("修改后:" + testService.getConfigId());
    8.       }
    9.   }
    10.   输出:
    11.   修改前:11111
    12.   22:35:40.628 [main] DEBUG org.springframework.test.util.ReflectionTestUtils - Setting field 'configId' of type [null] on target object [com.cf.springboot.TestServiceImpl@45018215] or target class [class com.cf.springboot.TestServiceImpl] to value [2222]
    13.   修改后:2222
    复制代码
    通过输出以及代码,可以看到非常的简单,一行代码即可完成私有属性的更改,是不是十分的方便!
      原理
      这里就简单贴一下代码,看看:
    1. public static void setField(@Nullable Object targetObject, @Nullable Class<?> targetClass, @Nullable String name, @Nullable Object value, @Nullable Class<?> type) {
    2.       Assert.isTrue(targetObject != null || targetClass != null, "Either targetObject or targetClass for the field must be specified");
    3.       if (targetObject != null && springAopPresent) {
    4.           targetObject = AopTestUtils.getUltimateTargetObject(targetObject);
    5.       }
    6.       if (targetClass == null) {
    7.           targetClass = targetObject.getClass();
    8.       }
    9.       Field field = ReflectionUtils.findField(targetClass, name, type);
    10.       if (field == null) {
    11.           throw new IllegalArgumentException(String.format("Could not find field '%s' of type [%s] on %s or target class [%s]", name, type, safeToString(targetObject), targetClass));
    12.       } else {
    13.           if (logger.isDebugEnabled()) {
    14.               logger.debug(String.format("Setting field '%s' of type [%s] on %s or target class [%s] to value [%s]", name, type, safeToString(targetObject), targetClass, value));
    15.           }
    16.           ReflectionUtils.makeAccessible(field);
    17.           ReflectionUtils.setField(field, targetObject, value);
    18.       }
    19.   }
    复制代码



    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 02:29 , Processed in 0.064015 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表