Android Unit Test Handle Expected Exception (Kotlin)

March 7, 2019

Solution 1: expected

Great for simple cases.

@Test(expected = IndexOutOfBoundsException::class)
fun testException() {
    val items = listOf(1, 2, 3)
    val value = items[10]
}

Solution 2: ExpectedException Rule

Sometimes detecting an exception class is not sufficient, where I need to

  • Detect the exception which cause this exception
  • Check the message of the exception
@Rule
@JvmField
val expectedException = ExpectedException.none()    

fun expectFirestorePermissionDenied() {
    expectedException.expect(ExecutionException::class.java)
    expectedException.expectCause(isA(FirebaseFirestoreException::class.java))
    expectedException.expectMessage(StringContains("PERMISSION_DENIED"))
}

@Test
fun createUserByPublic() {
    val task = db.collection("users")
        .document("test_create_user_public")
        .set(mapOf("roles" to listOf("user")))

    expectFirestorePermissionDenied()
    Tasks.await(task, 10, TimeUnit.SECONDS)
}    

Solution 3: Try Catch

@Test
fun testExceptionWithTryCatch() {
    try {
        val items = listOf(1, 2, 3)
        val value = items[10]
        fail("IndexOutOfBoundsException expected")
    } catch (e: IndexOutOfBoundsException) {
        assertThat(e.message, StringContains("Invalid index"))
    }
}

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.