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

使用mockito-kotlin测试Spring Batch StepScope处理器异常问题

使用Mockito-Kotlin测试Spring Batch StepScope组件时的存根冲突问题

问题描述

我在使用Mockito-Kotlin测试Spring Batch的StepScope处理器时遇到异常:testA执行完成后运行testB,原本期望myService.foo()返回"SomeValue",结果却抛出了IllegalArgumentException("myException")。排查后发现:

  • 堆栈信息指向testB的given语句行
  • 所有测试用例共用同一个myService Mock实例
  • 测试非StepScope的普通组件时无此问题
  • 将BDD风格的given().willReturn()存根改为doReturn().when(mock).myMethod()后问题解决

想问这是Bug还是预期情况?


测试代码示例

目标处理器代码

// Processor to test
@StepScope
@Component
class MyProcessor(
    private val myService: MyService
) {
    fun process(item: Item) {
        // doSomething
        myService.foo(arg1, arg2)
    }
}

测试类代码

// test
@SpringBootTest
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
class MyProcessorTest(
    private val myProcessor: MyProcessor,
    @MockBean private val myService: MyService
) {
    @Test
    fun testA() {
        given { myService.foo(any(), any()) } willThrow { IllegalArgumentException("myException") }
        myProcessor.process(Item(...))
    }

    @Test
    fun testB() {
        given { myService.foo(any(), any()) } willReturn { "SomeValue" }
        myProcessor.process(Item(...))
    }
}

问题分析与结论

这是预期情况,核心原因和Spring Batch的StepScope特性、Mockito的存根执行逻辑有关:

  • StepScope的代理特性:StepScope组件会被Spring包装为代理对象,调用process方法时,代理逻辑会触发目标方法执行,这个过程会干扰Mockito对方法调用的拦截时机。
  • BDD风格given的执行逻辑:Mockito-Kotlin的given { ... }语法糖会先执行一次目标方法调用(被Mockito拦截返回默认值),再完成存根设置。结合StepScope代理的特殊逻辑,testA中设置的willThrow存根会在testB执行given { myService.foo(...) }时被触发,导致抛出异常,无法完成新的存根设置。
  • doReturn的优势:doReturn().when(mock).myMethod()属于"存根优先"的语法,不会先执行目标方法,而是直接定义存根行为,因此不会触发之前设置的异常存根,能正常覆盖旧的存根逻辑。
  • 测试隔离补充:虽然Spring Boot Test默认会在每个测试方法后重置MockBean,但StepScope代理的特殊生命周期可能导致存根重置不及时。除了改用doReturn风格,也可以通过@MockBean(clear = MockReset.AFTER_EACH_TEST_METHOD)强制每个测试后重置存根。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:19:51