android - Mockk verify { ... } block 内缺少调用

标签 android static mockk

我有一个单元测试,它抛出在 verify { ... } block 内缺少调用。

在我将 PhoneNumberSelectionActivity 从 java 转换为 kotlin 之前,该单元测试运行良好。

转换前的样子:

@Test
fun `handle signed in but no phone number goes to PNS`() {
    mockSessionInfo(sessionId = "session", userName = "name", phone = null)

    mockkStatic(PhoneNumberSelectionActivity::class)
    every {
        PhoneNumberSelectionActivity.startActivity(
            mockActivity,
            any(),
            any()
        )
    } returns Unit

    assertFalse(authorizationUtils.handleNotSignedInNoPhoneNumber(mockActivity))

    verify { PhoneNumberSelectionActivity.startActivity(mockActivity, true, PhoneNumberSelectionActivity.ACTIVITY_HOST_TYPE.AUTHORIZATION) }
}

但是在转换之后我得到了但是我得到了:

Failed matching mocking signature for SignedCall(retValue=java.lang.Void@7a5aa8c5, isRetValueMock=false, retType=class java.lang.Void, self=TNActivityBase(mockActivity#1), method=startActivity(Intent), args=[null], invocationStr=TNActivityBase(mockActivity#1).startActivity(null)) left matchers: [any(), any()]

所以我将测试更改为:

@Test
fun `handle signed in but no phone number goes to PNS`() {
    mockSessionInfo(sessionId = "session", userName = "name", phone = null)

    mockkStatic(PhoneNumberSelectionActivity::class)
    mockkConstructor(PhoneNumberSelectionActivity::class)
    every {
        PhoneNumberSelectionActivity.startActivity(
            mockActivity,
            true,
            PhoneNumberSelectionActivity.ACTIVITY_HOST_TYPE.AUTHORIZATION
        )
    } returns mockk()

    every {phoneNumberSelectionActivity.startActivity(any())} returns Unit
    every {mockActivity.dismissProgressDialog()} just Runs

    assertFalse(authorizationUtils.handleNotSignedInNoPhoneNumber(mockActivity))


    verify { PhoneNumberSelectionActivity.startActivity(mockActivity, true, PhoneNumberSelectionActivity.ACTIVITY_HOST_TYPE.AUTHORIZATION) }
    verify { phoneNumberSelectionActivity.startActivity(any()) }
}

这是抛出缺少验证异常的模拟方法:

@JvmStatic
fun startActivity(
        host: Activity,
        phoneExpired: Boolean,
        @ACTIVITY_HOST_TYPE activityHostType: Int
) {
   if (sIsRunning) {
       return
   }
   sIsRunning = true
   val intent = Intent(host, PhoneNumberSelectionActivity::class.java)
   intent.putExtra(EXTRA_ACTIVITY_HOST_TYPE, activityHostType)
   if (phoneExpired) {
        intent.putExtra(EXTRA_SHOW_PHONE_EXPIRE_DIALOG, true)
   }
   intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
   host.startActivity(intent)
  }

以及authorizationUtils.handleNotSignedInNoPhoneNumber方法:

  fun handleNotSignedInNoPhoneNumber(activity: TNActivityBase): Boolean {
    val sessionInfo = vessel.getBlocking(SessionInfo::class)
    if (sessionInfo == null || !sessionInfo.signedIn) {
        Log.d(TAG, "User is not signed in so sending to sign in page")
        issueEventTracker.trackLogout(
            IssueEventTracker.LOGOUT_UNAUTHENTICATED,
            activity.javaClass.simpleName
        )
        Unregister.unregisterUser(activity)
        LauncherUtils.startLaunchActivity(activity)
        return false
    } else if (sessionInfo.phone.isNullOrEmpty()) {
        Log.d(TAG, "User does not have a phone number so sending to PNS")
        activity.dismissProgressDialog()
        PhoneNumberSelectionActivity.startActivity(
            activity,
            true,
            PhoneNumberSelectionActivity.ACTIVITY_HOST_TYPE.AUTHORIZATION
        )
        return false
    }

    return true
}

这是静态方法,我不知道如何修复它。

我认为问题出在 @ACTIVITY_HOST_TYPE ActivityHostType: Int 的 java 转换中 --

kotlin 转换之前:

private @ACTIVITY_HOST_TYPE
int activityHostType = ACTIVITY_HOST_TYPE.OTHER;

@IntDef({FRAGMENT_TRANSITION.AREA_CODE_TO_PHONE_SELECTION, FRAGMENT_TRANSITION.PHONE_SELECTION_TO_AREA_CODE})
@Retention(RetentionPolicy.SOURCE)
public @interface FRAGMENT_TRANSITION {
    int AREA_CODE_TO_PHONE_SELECTION = 0;
    int PHONE_SELECTION_TO_AREA_CODE = 1;
}

@IntDef({ACTIVITY_HOST_TYPE.AUTHORIZATION,
        ACTIVITY_HOST_TYPE.OTHER,
        ACTIVITY_HOST_TYPE.PERSONALIZED_ONBOARDING})
@Retention(RetentionPolicy.SOURCE)
public @interface ACTIVITY_HOST_TYPE {
    int OTHER = -1;
    int AUTHORIZATION = 0;
    int PERSONALIZED_ONBOARDING = 1;
}

kotlin 转换后:

@ACTIVITY_HOST_TYPE
private var activityHostType = ACTIVITY_HOST_TYPE.OTHER
@IntDef(
    flag = true,
    value = [FRAGMENT_TRANSITION.AREA_CODE_TO_PHONE_SELECTION, FRAGMENT_TRANSITION.PHONE_SELECTION_TO_AREA_CODE]
)
@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
annotation class FRAGMENT_TRANSITION {
    companion object {
        const val AREA_CODE_TO_PHONE_SELECTION = 0
        const val PHONE_SELECTION_TO_AREA_CODE = 1
    }
}


@IntDef(
    flag = true,
    value = [ACTIVITY_HOST_TYPE.OTHER, ACTIVITY_HOST_TYPE.AUTHORIZATION, ACTIVITY_HOST_TYPE.PERSONALIZED_ONBOARDING]
)
@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
annotation class ACTIVITY_HOST_TYPE {
    companion object {
        const val OTHER = -1
        const val AUTHORIZATION = 0
        const val PERSONALIZED_ONBOARDING = 1
    }
}

我的设置:

Mockk version: 'io.mockk:mockk:1.9.3'
OS: Android
kotlin version: = '1.4.32'
junit version: 4.12

最佳答案

您需要像这样模拟伴随对象:mockkObject(MyClass.Companion)。所以这变成了:

@Test
fun `handle signed in but no phone number goes to PNS`() {
    mockSessionInfo(sessionId = "session", userName = "name", phone = null)

    mockkObject(PhoneNumberSelectionActivity.Companion)
    every {
        PhoneNumberSelectionActivity.startActivity(
            mockActivity,
            any(),
            any()
        )
    } returns Unit

    assertFalse(authorizationUtils.handleNotSignedInNoPhoneNumber(mockActivity))

    verify { PhoneNumberSelectionActivity.startActivity(mockActivity, true, PhoneNumberSelectionActivity.ACTIVITY_HOST_TYPE.AUTHORIZATION) }
}

相关问题:mockkStatic and mockkObject doesn't mock companion objects in Android

关于android - Mockk verify { ... } block 内缺少调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69457113/

相关文章:

java - 如何实现每月最后一天重复闹钟

c++ - 模板问题 - 将函数作为参数传递时遇到问题(非静态成员函数的使用无效)

c++ - 文件范围的原子是否受初始化顺序失败的影响?

kotlin - 如何用确切的值调用MockKKt.verify?

java - Eclipse JUNO + ADT 23.0.2 资源 $NotFoundException

android - 是否有可能减慢 edittext 监听器的 react

android:从右到左TextInputLayout

java - 访问父类子类中静态类的 protected 成员

android - 如何检查一个方法是否没有被 mockk 调用?

MockK - 验证失败,参数不匹配