Testing Groovy元类重写java.time.Year静态方法now(),但生产代码在运行时没有使用now()的重写行为
我试图重写java.time.Year类的public static方法now(),因为我希望它返回不同的值,而不仅仅是当前年份。在我的生产代码中,我有一个正在测试的方法,它使用Year.now()方法,如下所示: 测试中的Java类Testing Groovy元类重写java.time.Year静态方法now(),但生产代码在运行时没有使用now()的重写行为,testing,groovy,overriding,runtime,spock,Testing,Groovy,Overriding,Runtime,Spock,我试图重写java.time.Year类的public static方法now(),因为我希望它返回不同的值,而不仅仅是当前年份。在我的生产代码中,我有一个正在测试的方法,它使用Year.now()方法,如下所示: 测试中的Java类 公共类SomeClass{ public LocalDate methodUnderTest(){ 返回年份。现在() .每月(一月) .第(1)天; } } 在Spock groovy测试中,我试图通过以下方式重写java.time.Year.now()方法:
公共类SomeClass{
public LocalDate methodUnderTest(){
返回年份。现在()
.每月(一月)
.第(1)天;
}
}
在Spock groovy测试中,我试图通过以下方式重写java.time.Year.now()方法:
我打算在我的生产代码methodUnderTest()方法中使用静态方法now()的重写行为
但是,该测试仅适用于2020年(当前年份),其他两个值2019和2021不起作用,因为生产代码中显然没有使用预期的重写行为。
为什么在运行时methodUnderTest()的生产代码中没有使用预期的重写行为?一些基本知识:
java.time.Year
是final
,即您不能通过常规方法创建模拟实例。在加载类时,需要使用特殊的类装入器取消该类的最终确定。我自己的工具仍在开发中,它提供了此功能。其他类似PowerMock的方法提供了更间接的方法,通过检测调用它们的类来帮助您存根最终类
Year.now()
不仅在final
类中,而且在static
中。除了Groovy方法外,Spock没有任何在板上存根静态方法的方法。同样,您的方法位于Java类中,也被Java类调用,所以这对您没有帮助。同样,Sarek或其他工具(如PowerMock)可以在这方面帮助您
戴夫·萨雷克
萨瑞克
1.0-快照
测试
戴夫·萨雷克
萨瑞克-斯波克分机
1.0-快照
测试
package de.scrum_master.stackoverflow.q65321086;
导入java.time.LocalDate;
导入java.time.Year;
导入静态java.time.Month.一月;
公共类{
public LocalDate methodUnderTest(){
返回年份。现在()
.每月(一月)
.第(1)天;
}
}
package de.scrum_master.stackoverflow.q65321086
导入dev.sarek.agent.mock.MockFactory
导入spock.lang.Specification
导入spock.lang.Subject
导入spock.lang.Unroll
导入java.time.LocalDate
导入java.time.Year
导入静态java.time.Month.一月
导入静态net.bytebuddy.matcher.ElementMatchers.named
类SomeClassTest扩展了规范{
@主题
SomeClass classUnderTest=新的SomeClass()
@展开
def“覆盖静态JRE方法Year.now()for#Year”(){
设置:
MockFactory MockFactory=MockFactory
.forClass(年份.类)
.mockStatic(
命名为(“现在”),
{方法,args->false},
{method,args,proceedMode,returnValue,throwable->Year.of(Year)}
)
.build()
期望:
classUnderTest.methodUnderTest()==expectedDate
清理:
mockFactory.close()
哪里:
年份| |预期
2019年| |当地日期(2019年1月1日)
2020年| |本地日期(2020年1月1日)
2021年| |当地日期(2021年1月1日)
}
}
我通过了这次考试。除了非常好的JavaDoc(检查源代码)和不同模块中的大量示例测试之外,Sarek还没有深入的文档或教程
至于Sarek,我计划将它集成到Spock中,甚至比现在更好,因此在将来使用它会让人感觉像是在模仿“spocky”。我最近很忙。但它已经完全可用,并且还集成到JUnit 4、JUnit 5和TestNG中。一些基本功能:
java.time.Year
是final
,即您不能通过常规方法创建模拟实例。在加载类时,需要使用特殊的类装入器取消该类的最终确定。我自己的工具仍在开发中,它提供了此功能。其他类似PowerMock的方法提供了更间接的方法,通过检测调用它们的类来帮助您存根最终类
Year.now()
不仅在final
类中,而且在static
中。除了Groovy方法外,Spock没有任何在板上存根静态方法的方法。同样,您的方法位于Java类中,也被Java类调用,所以这对您没有帮助。同样,Sarek或其他工具(如PowerMock)可以在这方面帮助您
戴夫·萨雷克
萨瑞克
1.0-快照
测试
戴夫·萨雷克
萨瑞克-斯波克分机
1.0-快照
测试
package de.scrum_master.stackoverflow.q65321086;
导入java.time.LocalDate;
导入java.time.Year;
导入静态java.time.Month.一月;
公共类{
public LocalDate methodUnderTest(){
返回年份。现在()
.每月(一月)
.第(1)天;
}
}
package de.scrum\u master.stackoverflow。
class SomeClassSpec extends Specification {
@Subject
SomeClass classUnderTest = new SomeClass()
def "test method with overriden behaviour"() {
setup:
Year.metaClass.'static'.now = { -> Year.of(year) }
expect:
classUnderTest .methodUnderTest() == expectedDate
where:
year || expectedDate
2019 || LocalDate.of(2019, JANUARY, 1)
2020 || LocalDate.of(2020, JANUARY, 1)
2021 || LocalDate.of(2021, JANUARY, 1)
}
}