首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin/Mockito:如何从kotlin.Annotation中模仿“kotlin.Annotation”

Kotlin/Mockito:如何从kotlin.Annotation中模仿“kotlin.Annotation”
EN

Stack Overflow用户
提问于 2020-12-04 23:57:02
回答 1查看 556关注 0票数 0

我想模拟注释,以检查根据给定注释返回结果的类的良好行为。

下面是我使用OneToOne注释检查良好行为的测试之一:

代码语言:javascript
复制
@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()返回

如果你不知道你为什么要克服错误,请继续读下去。由于上述语法的性质,可能会出现问题,因为:

  1. 这种异常可能发生在错误编写的多线程测试中。关于并发测试的限制,请参考Mockito。
  2. 间谍是使用when(spy.foo()).then()语法进行截取的。对间谍存根更安全一些--
    • 具有doRe移位、而今抛出()系列的方法。更多地介绍Mockito.spy() Mockito.spy的javadocs

当mockito调用以下代码时,会发生此错误:

代码语言:javascript
复制
onGeneric { this.annotationClass }.thenReturn(OneToOne::class)

如果我删除这一行,我就没有问题来模拟注释。(模仿'fetch‘属性非常有效),但我的测试没有通过,因为我需要模拟'annotationClass’

我不明白为什么有错误,为什么错误与annotationType() (java注释方法)有关?

有谁知道怎么解决这个问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-05 16:09:52

我找到了解决问题的办法。

kotlin.Annotation.annotationClass是kotlin扩展函数:

代码语言:javascript
复制
/**
 * 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>

此函数调用java.lang.annotation.Annotation.annotationType()

我不能模拟扩展函数,因为kotlin将扩展函数转换为静态方法,而Mockito不能存根静态方法。

所以我直接嘲笑java.lang.annotation.Annotation.annotationType()

这里是我的新代码:

代码语言:javascript
复制
@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()
}

有一些替代模拟静态方法(PowerMock,MockK)的方法,但我没有进行测试。

如果有人有更好的建议,我会感兴趣的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65152348

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档