工具类需验证私有构造器和静态方法:用反射检查构造器是否为private,或尝试调用并断言抛出IllegalAccessException;调用私有静态方法时invoke传null,可封装泛型工具简化反射操作。

工具类常含私有构造方法防止实例化,同时封装静态工具方法。测试这类类时,既要验证静态方法逻辑,也要确保构造器确实被设为私有——这是保障设计意图的关键一环。反射是目前最直接、稳定且无需额外依赖的手段。
验证私有构造方法不可被外部调用
核心目标不是“调用它”,而是证明它无法被正常访问。可通过反射尝试获取并调用,再断言抛出 IllegalAccessException 或 InvocationTargetException:
- 用
getDeclaredConstructor()获取构造器 - 调用
setAccessible(true)绕过访问检查(仅用于测试) - 执行
newInstance(),预期应抛出异常(因构造器内通常含throw new UnsupportedOperationException()) - 更严谨的做法是:不调用,只检查修饰符是否含
Modifier.PRIVATE
反射调用私有静态方法的通用写法
静态方法无对象实例,invoke 的第一个参数传 null 即可:
- 通过
getDeclaredMethod("methodName", paramTypes...)获取方法 - 必须调用
setAccessible(true) - 调用
method.invoke(null, args...)—— 注意此处传null,不是新实例 - 若方法抛异常,需在测试中捕获并验证,而非让测试崩溃
避免重复代码:轻量级工具方法封装
不必引入复杂工具类,一个静态泛型方法就够用:
- 接收类对象、方法名、参数类型数组、参数值数组
- 内部完成
getDeclaredMethod、setAccessible、invoke - 统一处理
Exception转为运行时异常,便于测试断言 - 示例调用:
invokeStatic(ToolClass.class, "doWork", new Class[]{String.class}, "test")
替代方案对比:mockito-inline 不适用此场景
Mockito-inline 解决的是“模拟”行为,比如替换静态方法的返回值;但它不能帮你调用一个本就不可见的私有静态方法。对工具类中真正需要验证逻辑的私有静态方法,反射仍是首选。只有当你想“跳过其真实执行、替换成桩结果”时,才考虑 mockito-inline + mockStatic,但那已不属于“测试该方法本身”的范畴。











