如何正确测试基于反射的Java Annotation库(无需Mock核心类)
测试自定义Annotation库的Null返回监听逻辑(无需Mock Method/Consumer)
方案1:自定义可观测的Consumer实现
自己实现一个带跟踪功能的Consumer,直接记录调用状态和参数,完全不需要Mock:
// 自定义跟踪型Consumer static class TrackedConsumer implements Consumer<TestedClass> { private boolean invoked = false; private TestedClass receivedInstance; @Override public void accept(TestedClass instance) { invoked = true; receivedInstance = instance; } // 提供验证用的方法 public boolean wasInvoked() { return invoked; } public TestedClass getReceivedInstance() { return receivedInstance; } }
对应的测试代码:
@Test void testNullReturnTriggersListener() { // 初始化自定义Consumer TrackedConsumer trackedConsumer = new TrackedConsumer(); Library<TestedClass> library = MyLibrary.register(TestedClass.class); library.setOnNullListener(trackedConsumer); // 触发返回null的方法调用(假设库会代理实例方法执行) TestedClass instance = library.getInstance(); instance.specialMethod(false); // 验证逻辑 assertTrue(trackedConsumer.wasInvoked()); assertNotNull(trackedConsumer.getReceivedInstance()); }
方案2:给测试类添加调用跟踪钩子
针对TestedClass写一个测试子类,跟踪register方法的调用情况,验证Consumer里的参数是否正确:
// 带跟踪的测试子类 static class TestableTestedClass extends TestedClass { private boolean registerCalled = false; private String registeredArg; // 假设原类有register方法,这里重写做跟踪 public void register(String value) { registerCalled = true; registeredArg = value; } // 验证用方法 public boolean isRegisterCalled() { return registerCalled; } public String getRegisteredArg() { return registeredArg; } }
测试代码:
@Test void testConsumerUsesCorrectArgument() { Library<TestableTestedClass> library = MyLibrary.register(TestableTestedClass.class); // 沿用原业务逻辑的Consumer library.setOnNullListener(obj -> obj.register("null")); // 触发null返回的方法 TestableTestedClass instance = library.getInstance(); instance.specialMethod(false); // 验证参数正确性 assertTrue(instance.isRegisterCalled()); assertEquals("null", instance.getRegisteredArg()); }
验证指定Method是否被调用
不需要Mock Method对象,通过给目标方法加跟踪间接验证:
static class TrackedMethodTestedClass extends TestedClass { private boolean specialMethodInvoked = false; @Override public String specialMethod(boolean b) { specialMethodInvoked = true; return super.specialMethod(b); } public boolean isSpecialMethodInvoked() { return specialMethodInvoked; } }
测试代码:
@Test void testLibraryDetectsTargetMethodCall() { TrackedMethodTestedClass trackedInstance = new TrackedMethodTestedClass(); TrackedConsumer consumer = new TrackedConsumer(); Library<TrackedMethodTestedClass> library = MyLibrary.register(TrackedMethodTestedClass.class); library.setOnNullListener(consumer); // 触发方法调用 trackedInstance.specialMethod(false); // 先验证方法确实被执行,再验证监听被触发 assertTrue(trackedInstance.isSpecialMethodInvoked()); assertTrue(consumer.wasInvoked()); }
内容的提问来源于stack exchange,提问作者Andret2344
相关产品推荐
相关产品推荐

