【问题标题】:Mocking a generic method in Kotlin在 Kotlin 中模拟一个泛型方法
【发布时间】:2018-10-08 11:11:53
【问题描述】:

我正在尝试编写一些涉及 JDKHttpClient from ScribeJava 的测试,因为我想模拟我用来为我的 API 进行自动化测试的 OAuth 服务。

模拟 execute 方法可以正常工作:

val mockClient : HttpClient = mock(JDKHttpClient::class.java)
val responseBody = "{\"access_token\": \"gotit\", \"token_type\": \"type\", \"expires_in\": 3600}"
whenever(mockClient.execute(anyString(), anyMap(), eq(Verb.GET), anyString(), any(ByteArray::class.java)))
   .thenReturn(Response(302, "ciao", emptyMap(), responseBody))

当仅模拟 execute 方法时,我在尝试获取访问令牌时收到 NPE,因为客户端尝试调用 executeAsync 变体。我的问题是我不知道如何模拟这些方法。显而易见的事情如下:

whenever(mockClient.executeAsync(anyString(), anyMap<String,String>(), eq(Verb.GET), anyString(),
    any(String::class.java),
    any(OAuthAsyncRequestCallback::class.java), 
    any(OAuthRequest.ResponseConverter::class.java))
).thenReturn(JDKHttpFuture(Response(302, "ciao", emptyMap(), responseBody)))

问题在于 Kotlin 编译器无法推断出这些方法的签名类型 T

public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
    byte[] bodyContents, 
    OAuthAsyncRequestCallback<T> callback, 
    OAuthRequest.ResponseConverter<T> converter) 

如何告诉 Kotlin 编译器正确的 T 类型? 是否有一些语法变化:

any(OAuthRequest.ResponseConverter::class.java)

这允许我显式设置与ResponseConverter 关联的T 类型?

【问题讨论】:

  • 当前版本的 Mockito 允许 any()(不带参数),因此您根本不必提供类参数。
  • @daniu 这并不能解决问题。事实上,从 IDE 中我看到了错误的数量增加。 (上面写着:Type inferencer failed 没有足够的信息来推断T)。
  • 看起来你在那里使用 kotlin-mockito。您是否尝试使用它的顶级 any() 函数而不是 Mockito 的 any(Class)
  • @s1m0nw1 在这两种情况下,使用 Mockito.any 或 kotlin-mockito 的 any,它表示没有足够的信息来推断类型 T
  • 你听说过mockk吗?它很容易解决这个问题

标签: generics kotlin mockito overloading


【解决方案1】:

回答原问题:

如何告诉 Kotlin 编译器 executeAsyncMethod() 的正确 T 类型

你可以在使用函数时给出类型参数。 例如,

whenever(mockClient.executeAsync<String>(...
... 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多