Is it possible to use non-kmm libraries, like Mock...
# multiplatform
a
Is it possible to use non-kmm libraries, like Mockito, for use in
commonTest
?
b
Nor quite. Jvm libs are only available for jvm targets
To use it in common your only option is to expect/actual into jvm lib api and implement it on all the other targets you have
j
MockK supports kmm. Not yet, actually.
l
You can also simply use fakes.
m
m
If I am not mistaken MockK doesn’t support Kotlin Native yet, I am happy with mockative so far
b
KMock (or any other ksp-based libs) are the only ones capable of full KMP support due to missing reflection on native and js
l
There's also one by Kodein that I'm 99% sure also supports Kotlin/Native.
j
@Mustafa Ozhan you're correct, sorry for the false info. I had a recollection of MockK working where Mockito did not. It was actually mockito-kotlin that doesn't work in Android, where MockK has similar Kotlin APIs that do.
a
I'm not entirely sure why I need to use a KMM testing library. It's not like my tests will target different platforms--they'll only be testing the code in
commonMain
. I did get Mockito working by moving my tests and test dependencies to
androidTest
. It works well except Android Studio doesn't do code completion on the classes in
commonMain
although code completion on Mockito etc works fine.
Thinking about it, if I want to use Mockito/MockK, I should put the tests in the Android project, or perhaps a separate module, and test the
commonMain
code from there.
j
That is one approach, if your code is entirely in the common module. However, if you have any expect/actual code that differs between JVM and native, you won't be exercising the native implementation, only the Android side. And while common Kotlin should behave the same on all platforms, especially with the new native memory model, it's usually a good idea to still be able to prove this in tests running on all supported platforms. I've seen some subtle differences, such as with the order of superclass and subclass initialization on Kotlin/JS vs JVM and Native (which is why it's a warning to access class state during init).
m
But what is wrong with the existing KMP variants?
j
Personally, I ran into the issue that KMP mocks can only mock interfaces and my KMP test case that used a mock wasn't mocking an interface, and the mocked object API wasn't my own to change. The tests were for KTX extension functions of another API.
m
For a external extension or internal? (Just curious in order to improve the adaptation for my little library)
j
The extensions are for a KTX supplemental library to enhance another library's API with Flows. It may be an atypical scenario, as the other library's API is not originally Kotlin. It's based on a database's Java and ObjC SDKs, which I wrapped with pure Kotlin expect/actual bindings. The original callback APIs are enhanced with Coroutines and Flows in the KTX extensions library, while keeping the KMP API the same as the underlying Java SDK. Since I did author the KMP bindings, I could look at inserting an interface into this portion of the API. But I didn't feel like modifying the database bindings library in order to be able to mock it for testing the KTX extensions. I also could have looked into testing without a mock, but the tests were already written for a version of the KTX extension on the original Java SDK, so I didn't bother rewriting.
m
I am curious - are you be willing to have a (much) prolonged compile time in order to get this capability on KMP?
j
I supposed it would depend on a number of factors. If the compilation only affected tests, it might be palatable.
m
Could you elaborate more on the factors, please? And for sure the time would only affect test...but is there any red line in your opinion?
j
It'd probably be acceptable if a test really needed a mock and if the overall compilation time was still within reason. My projects compile pretty fast on my machine currently. It could depend on the computer developers are using as well. It'd be difficult to define a red line, mostly because it would differ from case to case. I'd certainly try it out at the very least. Having the ability is a first step, which could hopefully be optimized for performance later.
577 Views