lupuuss / Mokkery

The mocking library for Kotlin Multiplatform, easy to use, boilerplate-free and compiler plugin driven.
https://mokkery.dev
Apache License 2.0
201 stars 8 forks source link

Mokkery & all-open plugin on WasmJs #25

Closed AndrazP closed 3 months ago

AndrazP commented 3 months ago

Hi!

I ran into an issue integrating Mokkery on WasmJs only Kotlin Multiplatform project. I suspect it's an all-open plugin issue, but I would like to hear your opinion.

So this works:

interface ExampleInterface
private val example: ExampleInterface = mock(MockMode.strict)

But my classes don't have interfaces and I don't want to change that. I see an alternative is using all-open plugin.

class Example {
  fun foo(): String = "" 
}
allOpen {
    annotation("kotlin.Metadata")
}

This does not seem to work at all. Mokkery still complains that class is final. So I have implemented a custom annotation.

allOpen {
    annotation("com.example.OpenForMokkery")
}

After this the error has changed:

Type 'com.example.Example' has final members and cannot be used with 'mock'! Final members: var _hashCode: Int, var typeInfo: Int

Are you familiar with this error? How can I confirm that classes are opened correctly?

lupuuss commented 3 months ago

Hi! What is your Kotlin version and Mokkery version?

AndrazP commented 3 months ago

Kotlin 2.0.0, Mokkery 2.1.1

lupuuss commented 3 months ago

I've found the problem and I should be able to fix this in the next release. As a workaround you can ignore final members in Gradle file:

mokkery {
    ignoreFinalMembers.set(true)
}
lupuuss commented 3 months ago

It's fixed. It will be available with the next release.

AndrazP commented 3 months ago

Thank you! Do you think it's a bug in all-open plugin?

lupuuss commented 3 months ago

Not really. It affects mocking classes in general. The problem is that Wasm has 2 extra internal final members in kotlin.Any - var _hashCode: Int and var typeInfo: Int. I'm not sure if they should be visible for compiler plugins, but they are. The simple fix is to ignore them when validating types to mock.