How to properly add mockk to android tests? The do...
# mockk
m
How to properly add mockk to android tests? The documentationsaus the following should suffice
Copy code
androidTestImplementation "io.mockk:mockk-android:${mockkVersion}"
androidTestImplementation "io.mockk:mockk-agent:${mockkVersion}"
But neither mockk-android nor mock-agent does include dependencies for mockk-jvm that contains all the methods like every, coEvery, verify etc. So how is it supposed to work?
a
hmm, that’s strange. Adding a dependency on
mockk-android
should automatically bring in the core
mockk
dependency, because it’s exposed using API https://github.com/mockk/mockk/blob/6587d9bc616111eb3423aa1b9ba4c27f1e3addbf/modules/mockk-android/build.gradle.kts#L21-L25
what version of MockK/Kotlin/Gradle/Android are you using? There was a change in the MockK layout about 6 months ago, so maybe you’re on an older version of MockK?
m
I have latest mockk 1.13.4.
image.png
Also the pom file references
mockk
and not
mockk-jvm
. But actually mock itself doesn’t have much inside
a
mockk
vs
mockk-jvm
is a Kotlin Multiplatform ‘thing’, which is unusual in MockK’s case because everything is JVM. But that shouldn’t concern Gradle users, since Gradle is clever so the
-jvm
suffix can be dropped
every, coEvery, verify etc should be inside the
MockK
file, a couple of files above the one you’ve selected
m
Apparently gradle is not that clever in my case as it didn’t work for me without the -jvm suffix. I have gradle 8.0 btw.
So now I wonder how does gradle determine which artifact it should pull
a
what does “didn’t work for me” look like?
the
-jvm
suffix really shouldn’t be necessary, unless you’re using some custom way of fetching dependencies. I wrote about what
-jvm
means and how it works under the hood if you want to take a look :) https://stackoverflow.com/q/73914158/4161471
m
I think it didn’t work the same simply not seeing all the mockk functions. But I will try again.
a
👍
try to check if it’s a problem with IntelliJ vs Gradle, by running
./gradlew check
on the command line
m
So switching back to just
mockk
without the -jvm didn’t help. The functions still cannot be resolved. And running from command line suffers the same problem
a
hmmm interesting
what’s the error message and/or stacktrace?
m
It’s basically kind of
Copy code
file://...CricketRepositoryIntegrationTest.kt:44:35 Unresolved reference: mockk
e: file://...CricketRepositoryIntegrationTest.kt:45:9 Unresolved reference: coEvery
e: file://...CricketRepositoryIntegrationTest.kt:45:19 Unresolved reference: getPopularEvents
e: file://...CricketRepositoryIntegrationTest.kt:45:36 Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
I think the gradle doesn;t know it should pull the jvm suffixed artifact
a
and those files are in
src/test/kotlin
?
I’m asking because I think Android has multiple types of test, right? (I’m not an Android dev, so I only have a vague understanding)
m
these ones actually in src/androidTest/kotlin
but the same problems with unit tests
a
can you try using
testApi "io.mockk:mockk-android:${mockkVersion}"
? I think that
testApi
should be available
using testApi is a bit of a shotgun approach, just to try and make sure that MockK is always available as a dependency
m
Available, but didn’t help
a
darn
how many subprojects do you have?
m
~30
a
how many of them are using Android and/or MockK?
m
most of them are android ones, part of the android ones are actually using Mockk
hmmm
a
hmmm, well I’m not sure what else to suggest. If
-jvm
works for you, then it works 🤷‍♀️
the only other thing I noticed this error
Copy code
e: file://...CricketRepositoryIntegrationTest.kt:45:19 Unresolved reference: getPopularEvents
that’s not a MockK function, so it might indicate some other dependency is missing?
m
what if… I have a maven proxy, so whenever we pull something from maven is is first cached in our internal server… and what if the modules files are not fetched from the original proxy…
a
that sounds unlikely… but not impossible!
Gradle tends to be pretty good with caching and validating dependencies
m
I wonder what would happen if this file cannot be seen by gradle https://repo1.maven.org/maven2/io/mockk/mockk/1.13.4/mockk-1.13.4.module
So we were missing these module files on our maven, but still putting them there didn;t help
a
ahh okay, yes if you were missing the .module files then you would need the -jvm suffix, because Gradle would have to rely on the Maven POM files which is missing the Gradle metadata
m
maybe I need to remove local gradle cache then
a
I was about to suggest the same!
m
Thanks for the comprehensive answers 🙏 🍺
a
my pleasure! Did you get it working?
m
Not yet, as I need to put my hands on the proxy server. But verified that it works fine if I use maven central directly. And that the .module files indeed are not queried from the original server and not stored on our proxy.
It also explains some issues we had with conflicting resources coming from META-INF directory. One was from the mock.jar which doesn't contain any classes but still contains some resources while the other one was from the mock-jvm.jar.
Normally when Gradle module metadata is considered the jar from the mock artifact is never downloaded but actually on the fly resolved to mockk-jvm. While when we fell back to POM we were getting both. The mockk.jar coming from transitive dependencies of the mock-android artifact. And the mockk-jvm.jar that we specified explicitly.
683 Views