测试保存在 Android Intent 中的值时出现问题(额外内容始终为空)

问题描述 投票:0回答:1

我有以下 Android Intent 扩展:

import android.content.Intent
import android.os.Parcelable
import java.io.Serializable

fun Intent.addNewTaskFlags(): Intent = apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_ANIMATION)
}

fun Intent.putData(dataMap: Map<String, Any?>): Intent = apply {
    dataMap.forEach { (key, data) ->
        data?.let {
            put(key, it)
        }
    }
}

private fun Intent.put(key: String, value: Any) {
    when (value) {
        is String -> putExtra(key, value)
        is Int -> putExtra(key, value)
        is Boolean -> putExtra(key, value)
        is Long -> putExtra(key, value)
        is Double -> putExtra(key, value)
        is Parcelable -> putExtra(key, value)
        is Serializable -> putExtra(key, value)
        else -> throw IllegalArgumentException("Incompatible data type: ${value.javaClass}")
    }
}

以及以下单元测试:

class IntentExtensionTest {

    @Test
    fun testAddNewTaskFlags() {
        // When
        val mockIntent = spyk(Intent())
        mockIntent.addNewTaskFlags()

        // Then
        verify {
            mockIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_ANIMATION)
        }
    }

    @Test
    fun testPutData() {
        // Given
        val parcelableValue = mockk<Parcelable>()
        val serializableValue = mockk<Serializable>()

        // When
        val intent = Intent().putData(
            mapOf(
                STRING_KEY to STRING_VALUE,
                INT_KEY to INT_VALUE,
                BOOLEAN_KEY to BOOLEAN_VALUE,
                LONG_KEY to LONG_VALUE,
                DOUBLE_KEY to DOUBLE_VALUE,
                PARCELABLE_KEY to parcelableValue,
                SERIALIZABLE_KEY to serializableValue
            )
        )

        // Then
        intent.run {
            val extras = extras ?: throw AssertionError("Intent extras are null")

            assertEquals(STRING_VALUE, extras.getString(STRING_KEY))
            assertEquals(INT_VALUE, extras.getInt(INT_KEY, -1))
            assertEquals(BOOLEAN_VALUE, extras.getBoolean(BOOLEAN_KEY, false))
            assertEquals(LONG_VALUE, extras.getLong(LONG_KEY, -1L))
            assertEquals(DOUBLE_VALUE, extras.getDouble(DOUBLE_KEY, -1.0))
            assertEquals(parcelableValue, extras.getParcelable(PARCELABLE_KEY))
            assertEquals(serializableValue, extras.getSerializable(SERIALIZABLE_KEY))
        }
    }

    companion object {
        private const val STRING_KEY = "stringKey"
        private const val STRING_VALUE = "Hello, World!"
        private const val INT_KEY = "intKey"
        private const val INT_VALUE = 1
        private const val BOOLEAN_KEY = "booleanKey"
        private const val BOOLEAN_VALUE = true
        private const val LONG_KEY = "longKey"
        private const val LONG_VALUE = 123456789L
        private const val DOUBLE_KEY = "doubleKey"
        private const val DOUBLE_VALUE = 3.14
        private const val PARCELABLE_KEY = "parcelableKey"
        private const val SERIALIZABLE_KEY = "serializableKey"
    }
}

测试

testPutData
下降并出现错误:

Intent extras are null
java.lang.AssertionError: Intent extras are null

为什么会发生这种情况以及如何解决?

android kotlin unit-testing android-intent
1个回答
0
投票

我想这种行为的原因已在here进行了描述。

但是,本地测试不能使用

Context
或其任何方法,因为它们属于Android框架。

在你的情况下,

Intent
没有被嘲笑。

您可能正在使用

unitTests.returnDefaultValues = true
,因为您没有收到 Method putExtra in android.content.Intent not mocked 错误。但通过此配置,
putExtra
不执行任何操作,并且
extras
为 null,从而产生
AssertionError

我认为您可以考虑测试扩展函数本身的行为,而不是测试它们调用的间接结果(即

extras
中的
Intent
属性)。事实上,
putExtras
修改
extras
属性是
Intent
内部实现的一部分,因此是对
Intent
类进行测试的问题。但对于这些扩展函数的测试,重要的是如何准确地调用这些
Intent
方法 - 例如调用了多少次,用什么参数调用,而不是进一步的影响,这就是隔离的意义。

© www.soinside.com 2019 - 2024. All rights reserved.