question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Mockito Kotlin is breaking with new type inference

See original GitHub issue

I’m referring to https://youtu.be/MyljSWm0Y_k?t=1282 I turned it on this way

    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
        kotlinOptions {
            // progressive helps detecting unstable Kotlin code earlier, see https://blog.jetbrains.com/kotlin/2018/06/kotlin-1-2-50-is-out/
            freeCompilerArgs = ["-Xjsr305=strict", "-progressive", "-XXLanguage:+NewInference", "-XXLanguage:+InlineClasses"]
            allWarningsAsErrors = true
        }
    }

The error is the following

e: /Users/rwondratschek/dev/projects/evernote/evernote/app/src/test/kotlin/com/evernote/EvernoteAppSetupRule.kt: (68, 64): Overload resolution ambiguity:
public inline fun <reified T : Any> mock(extraInterfaces: Array<KClass<out Any>>? = ..., name: String? = ..., spiedInstance: Any? = ..., defaultAnswer: Answer<Any>? = ..., serializable: Boolean = ..., serializableMode: SerializableMode? = ..., verboseLogging: Boolean = ..., invocationListeners: Array<InvocationListener>? = ..., stubOnly: Boolean = ..., @Incubating useConstructor: UseConstructor? = ..., @Incubating outerInstance: Any? = ...): TypeVariable(T) defined in com.nhaarman.mockitokotlin2
public inline fun <reified T : Any> mock(extraInterfaces: Array<KClass<out Any>>? = ..., name: String? = ..., spiedInstance: Any? = ..., defaultAnswer: Answer<Any>? = ..., serializable: Boolean = ..., serializableMode: SerializableMode? = ..., verboseLogging: Boolean = ..., invocationListeners: Array<InvocationListener>? = ..., stubOnly: Boolean = ..., @Incubating useConstructor: UseConstructor? = ..., @Incubating outerInstance: Any? = ..., stubbing: KStubbing<TypeVariable(T)>.(TypeVariable(T)) -> Unit): TypeVariable(T) defined in com.nhaarman.mockitokotlin2
@Deprecated public inline fun <reified T : Any> mock(a: Answer<Any>): TypeVariable(T) defined in com.nhaarman.mockitokotlin2

The issue should be easy to reproduce, basically every call like this fails

        val account = mock<AppAccount> {
            on { databaseHelper } doThrow IllegalStateException()
        }

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:3
  • Comments:5

github_iconTop GitHub Comments

2reactions
nhaarmancommented, Oct 30, 2018

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.

1reaction
wiyarmircommented, Oct 26, 2018

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...
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Mockito Kotlin is breaking with new type inference #302 - GitHub
The simplest solution is to remove the custom functions that accept a lambda and let the new type inference system handle this. However,...
Read more >
Kotlin requires type inference where Java doesn't : KT-5464
I have another issue raised on Spring Framework side due to Kotlin requiring type inference where Java doesn't. Not 100% sure this is...
Read more >
So about this new type inference feature is there some forma ...
results in things breaking due to overload resolution ambiguity, I'm curious what the options are to mitigate this?
Read more >
Kotlin Mockito Generics - Stack Overflow
error 1: Type inference failed. Expected type mismatch. error 2: Only classes are allowed on the left hand side of a class literal....
Read more >
On Kotlin: A Unit Test Conversion Guide | by Doug Arcuri
On the same topic of duality, another pattern that is prevalent in the standard library, and mocking frameworks like Mockito-Kotlin, is the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found