You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确测试基于反射的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:00:46