Mockk Missing calls inside verify { ... } 块

Mockk Missing calls inside verify { ... } block

我有一个单元测试抛出了 Missing calls inside 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) }
}

相关问题: