kosi-libs / MocKMP

A mocking processor for Kotlin Multiplatform
https://kosi-libs.org/mockmp
MIT License
183 stars 12 forks source link

New feature to generate for CommonMain not generating code #52

Open dalewking opened 1 year ago

dalewking commented 1 year ago

The new feature #47 does not appear to be working in that while it applies the runtime dependencies, no mock classes are generated. No ksp task is ran nor is a ksp task showing up in tasks and no build/generated/ksp folder is created

I am using 1.12.0 with the workaround I posted in #51 to use ksp for 1.7.21

dalewking commented 1 year ago

I think basically you have to do the same workaround you do for common test with common main

SalomonBrys commented 1 year ago

Doing the same workaround would be very bad for every other KSP lib. This feature is niche, so I am going to wait to see how KSP will properly support multiplatform.

dalewking commented 1 year ago

So I think the way to do this is not that you are generating it for the common code, but for each target. For example, for KMM you do it for kspAndroid, kspIosArm64, kspIosSimulatorArm64, kspIosX64. That is what I was able to do for Mockative (still trying to decide between MocKMP and Mockative)

dalewking commented 1 year ago

So I have this working for platform specific code without using your gradle plugin. So what I am doing is:

This actually works when you run it in gradle. The only issue is that in Android Studio the injectMocks call is showing as an error because that call is only part of the target, not the common code.

I am working around this using an expect/actual call to do the injection in each platform.

I think this could be resolved with some slight tweaks to MocKMP, borrowing an idea from Mockative. The idea would be to:

fun Mocker.injectMocks(instance: T) { // throw an exception because we only get here if there are no mocks for the given instance }

- So for each class that you you generate a .injectMocks function for (e.g. Foo in this example) you also generate:

package org.kodein.mock

fun Mocker.injectMocks(instance: Foo) = instance.injectMocks(this)



So in your class you call `Mocker.injectMocks(this)`

This satisfies Android Studio because it will resolve to the one in the runtime. When compiling for a platform it will pick up the one that was generated.