[英]Kotlin/Mockito: How to mock “annotationClass” from kotlin.Annotation
我想模拟注释以检查根据给定注释返回结果的 class 的良好行为。
这是我使用 OneToOne 注释检查良好行为的测试之一:
@Test
fun <T> supports_when_field_has_OneToOne_annotation_with_eager_fetch_type() {
val myHandler = MyHandler<T>()
val joinAnnotation = mock<OneToOne> {
on { this.fetch }.thenReturn(FetchType.EAGER)
onGeneric { this.annotationClass }.thenReturn(OneToOne::class)
}
val supports = myHandler.supports(joinAnnotation)
assertThat(supports).isTrue()
}
当我运行测试时,出现以下错误:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:KClassImpl 不能由 annotationType() 返回 annotationType() 应该返回 Class
如果您不确定为什么会出现上述错误,请继续阅读。 由于上述语法的性质,可能会出现上述问题,因为:
- 此异常可能发生在错误编写的多线程测试中。 有关并发测试的限制,请参阅 Mockito 常见问题解答。
- 使用 when(spy.foo()).then() 语法对间谍进行存根。 存根间谍更安全-
- 使用 doReturn|Throw() 系列方法。 更多关于 Mockito.spy() 方法的 javadocs。
当mockito调用以下代码时出现此错误:
onGeneric { this.annotationClass }.thenReturn(OneToOne::class)
如果我删除这一行,我可以毫无问题地模拟注解。 (模拟 'fetch' 属性效果很好),但我的测试没有通过,因为我需要模拟 'annotationClass'
我不明白为什么我有错误,为什么错误与 annotationType() (java 注释方法)有关?
有谁知道如何解决这个问题?
我找到了解决我的问题的解决方案。
kotlin.Annotation.annotationClass
是 kotlin 扩展 function:
/**
* Returns a [KClass] instance corresponding to the annotation type of this annotation.
*/
public val <T : Annotation> T.annotationClass: KClass<out T>
get() = (this as java.lang.annotation.Annotation).annotationType().kotlin as KClass<out T>
这个 function 调用java.lang.annotation.Annotation.annotationType()
I can't mock a extension function because kotlin converts extension functions into static methods and Mockito cannot stub static methods.
所以我直接嘲笑java.lang.annotation.Annotation.annotationType()
。
这是我的新代码:
@Test
fun <T> supports_when_field_has_OneToOne_annotation_with_eager_fetch_type() {
val myHandler = MyHandler<T>()
val joinAnnotation = mock<OneToOne> {
on { this.fetch }.thenReturn(FetchType.EAGER)
on { (this as java.lang.annotation.Annotation).annotationType() }.thenReturn(OneToOne::class.java)
}
val supports = myHandler.supports(joinAnnotation)
assertThat(supports).isTrue()
}
有模拟 static 方法(PowerMock,MockK)的替代方法,但我没有测试。
如果有人有更好的建议,我会很感兴趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.