Groovy Spock框架如何Mock Java类中的静态方法(如LocalDate.now())
Spock框架Mock Java静态方法实现方案
针对LocalDate.now()、Files.copy()这类JDK类静态方法的Mock需求,在Groovy Spock中有两种常用实现方式,适配不同场景:
方案1:使用Spock自带GroovyMock(仅适配待测试代码为Groovy的场景)
GroovyMock开启global:true参数后可以全局替换类的静态方法实现,写法简洁,无需额外引入依赖:
import spock.lang.Specification import java.time.LocalDate import java.time.Month class FunctionTest extends Specification { def "验证不同月份返回对应数值"() { given: "Mock LocalDate.now()返回指定月份的日期" GroovyMock(LocalDate, global: true) LocalDate.now() >> LocalDate.of(2024, testMonth, 1) when: "调用待测试方法" def result = functionForTest() then: "返回值符合预期" result == expected where: "覆盖多场景参数化测试" testMonth | expected Month.FEBRUARY | 55 Month.APRIL | 22 } }
注意:如果待测试方法是Java编写的,该方案对JDK类静态方法的Mock不会生效,需使用方案2。
方案2:使用Mockito-inline(适配待测试代码为Java的场景)
该方案依赖Mockito的静态Mock能力,需要先引入mockito-inline依赖(Gradle示例:testImplementation 'org.mockito:mockito-inline:4.11.0'),实现代码如下:
import spock.lang.Specification import org.mockito.Mockito import org.mockito.MockedStatic import java.time.LocalDate import java.time.Month class FunctionTest extends Specification { def "验证二月返回55"() { given: MockedStatic<LocalDate> mockedLocalDate = Mockito.mockStatic(LocalDate.class) mockedLocalDate.when(LocalDate::now).thenReturn(LocalDate.of(2024, Month.FEBRUARY, 1)) when: def result = functionForTest() then: result == 55 cleanup: "必须关闭Mock对象,避免影响其他测试用例" mockedLocalDate.close() } }
额外注意事项
- 静态方法Mock会影响全局,非必要不建议使用,更推荐通过依赖注入将日期工具类传入业务方法,从设计层面避免静态方法依赖的测试问题
- 并行测试场景下使用静态Mock需要严格做好作用域隔离,避免不同测试用例互相干扰
内容的提问来源于stack exchange,提问作者Mateusz Sobczak
相关产品推荐
相关产品推荐

