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

如何在Spock中Mock被测类注入实例的实例方法?

问题解答:用Spock Spy Mock Micronaut Bean的实例方法

是的,你完全可以通过Spock的Spy来Mock被测类ClassUnderTest自己的isRunning实例方法,只是当前的写法存在几个细节问题,导致Mock逻辑没有生效。下面我来拆解问题并给出调整方案:

问题根源

你手动调用Spy(classUnderTest)的方式,和Micronaut的依赖注入代理机制产生了冲突。Micronaut的@Singleton Bean默认是代理对象,当你Spy这个代理时,方法调用会被转发到原始的真实实例,导致你的Stubbing逻辑没有被触发。此外,Spock中Spy的交互验证和Stubbing顺序也需要注意,确保Mock逻辑在方法执行前被正确绑定。

解决方案

方案一:用Spock的@Spy注解直接注入被测类

这种方式最适配Micronaut的测试场景,让Spock自动为注入的Bean创建Spy代理,无需手动调用Spy()方法:

class MyTestClass extends Specification {
    @Subject
    @Spy // 新增@Spy注解,让Spock代理这个注入的Bean
    @Inject
    ClassUnderTest classUnderTest

    Event sampleEvent = getMockEvent();

    def "test1" () {
       given:
       // 提前设置Stubbing,确保调用isRunning时返回false
       classUnderTest.isRunning(_ as Long) >> false

       when:
       def res = classUnderTest.callTestMethod(sampleEvent)

       then:
       // 验证isRunning确实被调用了一次
       1 * classUnderTest.isRunning(sampleEvent.id)
       res != null
    }

    def getMockEvent() {
       new Event(/* Some attributes here */)
    }
}

方案二:手动创建实例并Spy(适合轻量测试场景)

如果不需要Micronaut注入完整依赖,可以手动创建被测类实例,Mock它的依赖后再Spy:

class MyTestClass extends Specification {
    Event sampleEvent = getMockEvent();

    def "test1" () {
       given:
       // Mock依赖的class1Instance
       Class1 class1Mock = Mock()
       // 手动初始化被测类,注入Mock的依赖
       ClassUnderTest classUnderTest = new ClassUnderTest(class1Instance: class1Mock)
       // 创建Spy实例
       def classUnderTestSpy = Spy(classUnderTest)
       // 设置Stubbing逻辑
       classUnderTestSpy.isRunning(_ as Long) >> false

       when:
       def res = classUnderTestSpy.callTestMethod(sampleEvent)

       then:
       1 * classUnderTestSpy.isRunning(sampleEvent.id)
       res != null
    }

    def getMockEvent() {
       new Event(/* Some attributes here */)
    }
}

关键注意点

  • 确保isRunning方法不是final的:Spock的Spy无法拦截final方法,你的代码中该方法是public非final,符合要求。
  • 优先用方案一:如果测试需要依赖Micronaut的注入生态(比如读取配置值${com.myapplication.property}),方案一能保留完整的Bean生命周期,测试更贴近真实场景。

内容的提问来源于stack exchange,提问作者suvodipMondal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:20:31