Open vRallev opened 6 years ago
I have a similar issue.
verify(someBean).genericMethod(org.mockito.ArgumentMatchers.any())
// --> compiles
verify(someBean).genericMethod(com.nhaarman.mockitokotlin2.any())
// --> Type inference failed: Not enough information to infer parameter T
Comparing the type signatures:
public static <T> T any() { ... }
inline fun <reified T : Any> any(): T { ... }
Not that much of a difference. It seems that inline
is not ideal here?
(This is with Kotlin 1.2.71.)
I've got a less cosmetic solution which is to specify the parameter name, so the overload resolution works.
val account = mock<AppAccount>(stubbing = {
// on {} etc...
})
This is something that breaks compilation of the library itself as well when -XXLanguage:+NewInference
is enabled. Since there isn't any (at least I haven't found any) official documentation or discussion available on this "new type inference" system, it's hard to tell how the Kotlin team will handle issues like these.
One specific case in the library itself is argThat(T.() -> Boolean)
and argThat(ArgumentMatcher)
, which results in the following compilation error:
e: /home/nhaarman/dev/nhaarman/mockito-kotlin/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt: (93, 12): Overload resolution ambiguity:
public inline fun <reified T : Any> argThat(noinline predicate: TypeVariable(T).() -> Boolean): TypeVariable(T) defined in com.nhaarman.mockitokotlin2
public inline fun <reified T : Any> argThat(matcher: ArgumentMatcher<TypeVariable(T)>): TypeVariable(T) defined in com.nhaarman.mockitokotlin2
The simplest solution is to remove the custom functions that accept a lambda and let the new type inference system handle this. However, this is a breaking change and will affect users that don't have the new type inference system enabled. Since the -XXLanguage:+NewInference
is an internal compiler argument, I'm favoring for not addressing this issue in 2.x.
I know it's a pain for people that do have this flag enabled, but stuff like this is expected for experimental features.
3.x might be able to support his, but for support for the new type inference to have any standing at least some official documentation and stance from the Kotlin team needs to be available, and the feature needs to be stable.
@vRallev @reitzig @wiyarmir Is this still an issue with kotlin 1.3.40-eap-32 where the new type inference is enabled by default?
I don't have access anymore to the codebase I observed this in. Now (Kotlin 1.3.40) I have trouble reproducing.
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import org.junit.Test
interface Mockable {
fun <T> mockMe(m: T) : String
}
class Foo(val m: Mockable) {
fun bar() : String = "${m.mockMe("me")}, Amadeus!"
}
internal class SomeTest {
@Test
fun testBar() {
val mock = mock<Mockable> {
on { mockMe(any<String>()) } doReturn "Mock me"
}
val foo = Foo(mock)
println(foo.bar())
verify(mock).mockMe(org.mockito.ArgumentMatchers.any())
verify(mock).mockMe(com.nhaarman.mockitokotlin2.any())
}
}
Both variants are red.
If the type parameter lives on interface, not method level, both are green:
interface Mockable<T> {
fun mockMe(m: T) : String
}
class Foo(val m: Mockable<String>) {
fun bar() : String = "${m.mockMe("me")}, Amadeus!"
}
internal class SomeTest {
@Test
fun testBar() {
val mock = mock<Mockable<String>> {
on { mockMe(any()) } doReturn "Mock me"
}
val foo = Foo(mock)
println(foo.bar())
verify(mock).mockMe(org.mockito.ArgumentMatchers.any())
verify(mock).mockMe(com.nhaarman.mockitokotlin2.any())
}
}
I'm referring to https://youtu.be/MyljSWm0Y_k?t=1282 I turned it on this way
The error is the following
The issue should be easy to reproduce, basically every call like this fails