如何使用Mockk测试Intent的Bundle?

3

我希望测试一个自定义的处理程序类,该类正在启动一个新的Activity。我想测试IntentBundle是否包含预定义的参数。

测试类

@MockK
lateinit var activity: ActivityCalendar

@Before
fun setUp() {
    MockKAnnotations.init(this)
}

@Test
fun testActivityBundles() {
    val book = mockk<Book>()

    every { book.releaseDate } returns GregorianCalendar().apply { this.timeInMillis = 1423825586000 }
    every { activity.startActivity(any()) } just Runs

    val handler = ActivityHandler(activity)
    handler.startRequiredActivity(book)

    verify { activity.startActivity(
            withArg { intent ->
                val bundle = intent.extras!!
                val releaseDateTimeMillis = bundle.getLong("release_date", 0L)

                Assert.assertEquals(1423825586000, releaseDateTimeMillis)
            }
    ) }
}

上面的代码在第val bundle = intent.extras!!行崩溃了,但它不应该这样。

我想测试的类:

class ActivityHandler(val activity: Activity) {
    fun startRequiredActivity(book: Book) {
        val intent = buildIntent(book)

        activity.startActivity(intent)
    }

    private fun buildIntent(book: Book): Intent {
        val extras = Bundle().apply {
            this.putLong("release_Date", book.releaseDate.timeInMillis)
        }

        return Intent(activity, ActivityBookDetails::class.java).apply {
            putExtras(extras)
        }
    }
}

data class Book(
        val releaseDate: GregorianCalendar
)

我调试代码后发现private fun buildIntent(book: Book): Intent函数返回了一个“null”对象(即字符串“null”,而不是Java的空值)。


你最后确定了这个问题的答案吗?我刚好遇到了同样的问题。 - adrem7
2个回答

0
你会得到那个奇怪的Intent,因为你需要一个支持测试工具,因为Intent是核心Android库的一部分,需要在设备上运行。我假设你想避免在模拟器上进行测试,所以你也可以使用Roboelectric。这在这个thread中已经讨论过了。

0
这是Mockk对Intent进行嘲笑的一个例子。
你需要模拟hasExtra
every { intentMock.hasExtra("Your key") } returns true

完整示例:
 @Test
fun `Test`() {
    // Arrange
    val longValue = 1000L
    val enumValue = ModelEnum.MODEL1
    val intentMock = spyk<Intent>()
    every { intentMock.extras?.getLong("KEY_LONG_VALUE") } returns longValue
    every { intentMock.hasExtra(CheckoutRouter.RESULT_PAYMENT_TYPE) } returns true
    every { intentMock.getSerializableExtra("KEY_ENUM_VALUE") } returns enumValue

    // Action
    val a = A(intent = intentMock)
    val longValueResult = a.getLongValue()
    val enumValueResult =  a.getEnumValue()

    // Assert
    Assert.assertEquals(longValue, longValueResult)
    Assert.assertEquals(enumValue, enumValueResult)
}

class A (val intent: Intent){

    fun getLongValue():Long? {
        return intent.extras?.getLong("KEY_LONG_VALUE")
    }

    fun getEnumValue():ModelEnum? {
        return intent.getSerializableExtra("KEY_ENUM_VALUE") as? ModelEnum
    }
}

enum class ModelEnum{
    MODEL1,MODEL2
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接