kotlin/mockito:如何从kotlin.annotation模拟“annotationclass”

xcitsw88  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(303)

我想模拟注解来检查根据给定注解返回结果的类的良好行为。
以下是我的一个测试,用于检查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()应返回类
如果您不确定为什么会出现上述错误,请继续阅读。由于上述语法的性质,出现问题的原因可能是:
此异常可能发生在错误编写的多线程测试中。关于并发测试的限制,请参考mockito faq。
spy是使用when(spy.foo()).then()语法生成的。更安全的做法是把间谍留下来-
使用doreturn | throw()方法家族。有关mockito.spy()方法的更多信息,请参阅javadocs。
mockito调用以下代码时发生此错误:

onGeneric { this.annotationClass }.thenReturn(OneToOne::class)

如果我删除这一行,我就可以模拟注解(模拟'fetch'属性可以很好地工作),但是我的测试没有通过,因为我需要模拟'annotationclass'
我不明白为什么我有一个错误,为什么这个错误与annotationtype()有关(java annotation method)?
有人知道怎么解决这个问题吗?

xbp102n0

xbp102n01#

我找到了解决问题的办法。 kotlin.Annotation.annotationClass 是kotlin扩展函数:

/**
 * 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() .
这是我的新代码:

@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),但我没有进行测试。
如果有人有更好的建议,我很想看看。

相关问题