Hi, I am trying to get my first Kotlin unit test r...
# mockk
m
Hi, I am trying to get my first Kotlin unit test running - using MockK. Running the test results in failure. This is my class to be tested:
Copy code
class Client(private val context: Context) {
    fun sendCommandString(command: String, parameter: String) {
        val intent = Intent()
        intent.action = Intents.ACTION_DATAWEDGE
        intent.putExtra(command, parameter)
        intent.putExtra(Intents.EXTRA_SEND_RESULT, "true")
        context.sendBroadcast(intent)
    }
}
and this is my test:
Copy code
class ClientTest : MockkUnitTest() {
    @RelaxedMockK
    lateinit var context: Context

    @Test
    fun verifySendCommandString() = runTest {
        // Arrange
        every { context.sendBroadcast(any()) } returns Unit
        val client = Client(context)

        // Act
        client.sendCommandString("some command", "some parameter")

        // Assert
        verify(exactly = 1) {
            context.sendBroadcast(withArg {
                Truth.assertThat(it.action).isEqualTo(Intents.ACTION_DATAWEDGE)
                Truth.assertThat(it.extras).isNotNull()
                Truth.assertThat(it.extras!!.containsKey("some command")).isTrue()
                Truth.assertThat(it.getStringExtra("some command")).isEqualTo("some parameter")
                Truth.assertThat(it.extras!!.containsKey(Intents.EXTRA_SEND_RESULT)).isTrue()
                Truth.assertThat(it.getStringExtra(Intents.EXTRA_SEND_RESULT)).isEqualTo("true")
            })
        }
    }
}
The error is:
Method setAction in android.content.Intent not mocked.
. Well - I know. There should be no need to mock this method. I only have mocked the context to ensure, a correct
intent
has been created. (also posted on StackOverflow: https://stackoverflow.com/questions/76287781/test-complains-about-unmocked-method)
e
not a mockk issue. all Android APIs are stubs that throw when running unit tests
m
Just tried to evaluate on that, too… I found:
Copy code
testOptions {
  unitTests.returnDefaultValues = true
}
This at least causes the test to not complain as mentioned above
e
right, that replaces the stub
android.jar
with a modified stub whose methods don't throw, but do nothing instead
m
OK - then I have to get back to StackOverflow, as now this obviously causes
Intent()
to result in
null
e
there are libraries such as Robolectric which provide a fake Android implementation for unit tests
but for the most part, if code touches an Android API, I'd consider it no longer a unit test
m
Oh - OK… I already heard of this but obviously misinterpreted its type
but for the most part, if code touches an Android API, I’d consider it no longer a unit test
OK - I understand
e
well, the Android build system only has two types of tests, "unit" tests and instrumented tests, and it is nice to use "unit" tests as much as possible because they run on the (much faster) host machine
unfortunately we're stuck with the naming :-/
m
Thanks a lot for your reply and the insights. I removed the
testOptions
block from above (docs say to use it as a last resort) and converted the test to a robolectric test… works fine now… I will put the result as an answer on StackOverflow
281 Views