https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
a

Ayla

12/11/2023, 2:49 PM
I wrote the following code:
Copy code
//commonMian
expect fun isOnMainThread():Boolean
//androidMain
actual fun isOnMainThread()=Looper.getMainLooper().isCurrentThread
when I wrote a test in
commonTest
and test in android:
Copy code
@kotlin.test.Test
fun test(){
  //...do some things
  assertTrue(isOnMainThread())
}
It reported the following error:`Method getMainLooper in android.os.Looper not mocked.` I know how to run tests using android local tests with mocking frameworks, or simply using Instrumented tests, but how should I integrate them with the KMP project?
e

ephemient

12/11/2023, 3:23 PM
same way you would for unit tests in a pure Android project
either don't use the android framework in unit tests, or use a fake implementation like robolectric
👍 1
a

Andrii Yanechko

12/11/2023, 4:19 PM
Yeah, you can put android unit test under the
androidUnitTest
folder and use Robolectric
👍 1
j

Jacob Ras

12/11/2023, 5:48 PM
Although using Robolectric for this specific test would be testing Robolectric's implementation and not the actual functionality 😉 But I assume there's more to this test that makes it useful.
👍 1
j

Jan Holešovský

12/11/2023, 7:21 PM
@Ayla Any chance to also share where exactly are the files stored in the project (if in shared/ somewhere, or elsewhere), your build.gradle.kts that is supposed to build the test, and full log of the error? Maybe it will ring bell for somebody here...
👍 1
c

coachroebuck

12/11/2023, 10:05 PM
I just happened to read this thread. You might be able to customize the implementation of fun isOnMainThread() directly inside the unitTest package. You'll have to make sure that the package where your customized implementation resides remains unchanged. I have done this before, and noticed that the compiler had replaced the "default" implementation of the target module. Alternatively, if you're using a unit testing framework like Mockk, I see that Looper.getMainLooper() is a static method. You have the option to mock the Looper class. Depending on who you talk to, this may be ill advised, in favor of, for instance, following SOLID principles instead.
👍 1
If I were in your situation, I would attempt to import the Mockk dependency and mock that Looper.getMainLooper class.
Copy code
import android.os.Looper
import io.mockk.every
import io.mockk.mockkStatic

// ...

// Mocking Looper.getMainLooper() using MockK
mockkStatic(Looper::class)

// Provide a mock Looper instance for Looper.getMainLooper()
val mockMainLooper = mockk<Looper>()
every { Looper.getMainLooper() } returns mockMainLooper

// Now you can use mockMainLooper as a mocked instance of Looper.getMainLooper()

// Remember to clear the mocks after your test
after { unmockkAll() }
thank you color 1
2 Views