Skip to content

Some tests can not mock class in Java17 #518

Open
@ArpitPatel009

Description

@ArpitPatel009

BEFORE

Java 11
gradle-7.5.1
AGP 7.4.2
mockitoAndroid = "5.3.1"
mockitoKotlin = "5.1.0"
App Debug & Release build successful ✅
Unit tests suit successful ✅

AFTER UPGRADE

Java 17
gradle-8.6
AGP 8.4.2
mockitoAndroid = "5.3.1"
mockitoKotlin = "5.1.0"
App Debug & Release build successful ✅
Some Unit tests unsuccessful ❌

Sample tests

import androidx.compose.ui.test.junit4.createEmptyComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import ca.manulife.MobileBanking.configuration.LocalConfig
import ca.manulife.MobileBanking.dashboard.ui.AccountDashboardViewModel
import ca.manulife.MobileBanking.helpers.DaggerHelper
import ca.manulife.MobileBanking.helpers.ServiceHelper
import ca.manulife.MobileBanking.insights.InsightContentViewModel
import ca.manulife.MobileBanking.login.views.LoginActivity
import ca.manulife.MobileBanking.rules.LazyActivityScenarioRule
import ca.manulife.MobileBanking.viewmodels.LiveData.CustomerDetailsViewModel
import ca.manulife.MobileBanking.viewmodels.LiveData.MainActivityViewModel
import com.manulife.chatbot.ChatbotRepository
import com.manulife.chatbot.models.live_data.ChatbotResponseViewModel
import com.manulife.chatbot.models.live_data.ChatbotViewModel
import com.manulife.chatbot.services.ChatbotServiceHelper
import kotlinx.coroutines.flow.MutableStateFlow
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.Is.`is`
import org.hamcrest.core.IsNull.notNullValue
import org.hamcrest.core.IsNull.nullValue
import org.junit.After
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Answers
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.robolectric.Shadows.shadowOf

@RunWith(AndroidJUnit4::class)
class MainActivityLogoutTests {
    @get:Rule
    val activityScenarioRule = LazyActivityScenarioRule(createEmptyComposeRule(), MainActivity::class.java)

    @Mock
    private lateinit var serviceHelper: ServiceHelper

    @Mock
    private lateinit var chatbot: ChatbotServiceHelper

    @Mock
    private lateinit var viewModel: MainActivityViewModel

    @Mock
    private val chatbotVm = mock<ChatbotViewModel>()

    @Mock
    private val chatbotReponseVM = mock<ChatbotResponseViewModel>()

    @Mock
    private val customerDetailsViewModel = mock<CustomerDetailsViewModel>()

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        viewModel = DaggerHelper.setViewModel(defaultAnswer = Answers.RETURNS_MOCKS) {
            on { config } doReturn LocalConfig()
        }
        val sf = MutableStateFlow(true)
        DaggerHelper.setViewModel<ChatbotViewModel>(defaultAnswer = Answers.RETURNS_MOCKS) {}
        DaggerHelper.setViewModel<ChatbotResponseViewModel>(defaultAnswer = Answers.RETURNS_MOCKS) {}
        DaggerHelper.setViewModel<CustomerDetailsViewModel>(defaultAnswer = Answers.RETURNS_MOCKS) {}
        DaggerHelper.setViewModel<AccountDashboardViewModel>(defaultAnswer = Answers.RETURNS_MOCKS) {
            on { isRefreshing } doReturn MutableStateFlow(true)
        }
        DaggerHelper.setViewModel<InsightContentViewModel>(defaultAnswer = Answers.RETURNS_MOCKS) {}

        ServiceHelper.setInstance(serviceHelper)
        ChatbotServiceHelper.setInstance(chatbot)

        activityScenarioRule.launch()
    }

    @After
    fun tearDown() {
        ServiceHelper.setInstance(null)
        ChatbotServiceHelper.setInstance(null)
        DaggerHelper.reset()
    }

    @Test
    fun logout_closesTheActivity() {
        // arrange

        // act
        activityScenarioRule.scenario.onActivity {
            it.logout()

            // assert
            assertThat("MainActivity should finish() when it opens the LoginActivity",
                    it.isFinishing, `is`(true))
        }
    }

}

Error

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class fake.package.name.resourses.Resource.

If you're not sure why you're getting this error, please open an issue on GitHub.


Java               : 17
JVM vendor name    : JetBrains s.r.o.
JVM vendor version : 17.0.10+0-17.0.10b1087.21-11572160
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 17.0.10+0-17.0.10b1087.21-11572160
JVM info           : mixed mode
OS name            : Mac OS X
OS version         : 14.5


You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

Underlying exception : org.mockito.exceptions.base.MockitoException: Unsupported settings with this type 'fake.package.name.resourses.Resource'
	at fake.package.name.viewmodels.LiveData.MainActivityViewModel.getAccounts(MainActivityViewModel.kt:29)
	at fake.package.name.MainActivity.setUpBottomBarFragments(MainActivity.java:489)
	at fake.package.name.MainActivity.onCreate(MainActivity.java:216)
	at android.app.Activity.performCreate(Activity.java:8290)
	at android.app.Activity.performCreate(Activity.java:8269)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
	at org.robolectric.android.internal.RoboMonitoringInstrumentation.callActivityOnCreate(RoboMonitoringInstrumentation.java:295)
	at org.robolectric.android.controller.ActivityController.lambda$create$0(ActivityController.java:130)
	at org.robolectric.shadows.ShadowPausedLooper.runPaused(ShadowPausedLooper.java:204)
	at org.robolectric.android.controller.ActivityController.create(ActivityController.java:128)
	at org.robolectric.android.controller.ActivityController.create(ActivityController.java:138)
	at org.robolectric.android.internal.RoboMonitoringInstrumentation.startActivitySyncInternal(RoboMonitoringInstrumentation.java:108)
	at org.robolectric.android.internal.LocalActivityInvoker.startActivity(LocalActivityInvoker.java:35)
	at org.robolectric.android.internal.LocalActivityInvoker.startActivity(LocalActivityInvoker.java:40)
	at androidx.test.core.app.ActivityScenario.launchInternal(ActivityScenario.java:362)
	at androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:202)
	at fake.package.name.rules.LazyActivityScenarioRule._init_$lambda$1(LazyActivityScenarioRule.kt:40)
	at fake.package.name.rules.LazyActivityScenarioRule.launch(LazyActivityScenarioRule.kt:60)
	at fake.package.name.MainActivityLogoutTests.setUp(MainActivityLogoutTests.kt:79)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at app//org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
	at app//org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
	at app//org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1$evaluate$1.invoke(AndroidComposeTestRule.android.kt:272)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1$evaluate$1.invoke(AndroidComposeTestRule.android.kt:271)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$AndroidComposeUiTestImpl.withDisposableContent(ComposeUiTest.android.kt:491)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1$1$1.invoke(ComposeUiTest.android.kt:323)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withComposeIdlingResource(ComposeUiTest.android.kt:375)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withComposeIdlingResource(ComposeUiTest.android.kt:228)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1$1.invoke(ComposeUiTest.android.kt:322)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withWindowRecomposer(ComposeUiTest.android.kt:349)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withWindowRecomposer(ComposeUiTest.android.kt:228)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1.invoke(ComposeUiTest.android.kt:321)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:362)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:228)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:320)
	at androidx.compose.ui.test.junit4.IdlingStrategy.withStrategy(IdlingStrategy.android.kt:52)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:319)
	at androidx.compose.ui.test.junit4.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:157)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:318)
	at androidx.compose.ui.test.junit4.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:317)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1.evaluate(AndroidComposeTestRule.android.kt:271)
	at app//org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:580)
	at app//org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:287)
	at app//org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:99)
	at [email protected]/java.util.concurrent.FutureTask.run(Unknown Source)
	at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at [email protected]/java.lang.Thread.run(Unknown Source)
	Suppressed: org.robolectric.android.internal.AndroidTestEnvironment$UnExecutedRunnablesException: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(Looper.getMainLooper()).idle() call.
Caused by: org.mockito.exceptions.base.MockitoException: Unsupported settings with this type 'fake.package.name.resourses.Resource'
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
	at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
	at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
	at fake.package.name.viewmodels.LiveData.MainActivityViewModel.getAccounts(MainActivityViewModel.kt:29)
	at fake.package.name.MainActivity.setUpBottomBarFragments(MainActivity.java:489)
	at fake.package.name.MainActivity.onCreate(MainActivity.java:216)
	at android.app.Activity.$$robo$$android_app_Activity$performCreate(Activity.java:8290)
	at android.app.Activity.performCreate(Activity.java)
	at android.app.Activity.$$robo$$android_app_Activity$performCreate(Activity.java:8269)
	at android.app.Activity.performCreate(Activity.java)
	at android.app.Instrumentation.$$robo$$android_app_Instrumentation$callActivityOnCreate(Instrumentation.java:1384)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java)
	at org.robolectric.android.internal.RoboMonitoringInstrumentation.callActivityOnCreate(RoboMonitoringInstrumentation.java:295)
	at org.robolectric.android.controller.ActivityController.lambda$create$0(ActivityController.java:130)
	at org.robolectric.shadows.ShadowPausedLooper.runPaused(ShadowPausedLooper.java:204)
	at org.robolectric.android.controller.ActivityController.create(ActivityController.java:128)
	at org.robolectric.android.controller.ActivityController.create(ActivityController.java:138)
	at org.robolectric.android.internal.RoboMonitoringInstrumentation.startActivitySyncInternal(RoboMonitoringInstrumentation.java:108)
	at org.robolectric.android.internal.LocalActivityInvoker.startActivity(LocalActivityInvoker.java:35)
	at org.robolectric.android.internal.LocalActivityInvoker.startActivity(LocalActivityInvoker.java:40)
	at androidx.test.core.app.ActivityScenario.launchInternal(ActivityScenario.java:362)
	at androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:202)
	at fake.package.name.rules.LazyActivityScenarioRule._init_$lambda$1(LazyActivityScenarioRule.kt:40)
	at fake.package.name.rules.LazyActivityScenarioRule.launch(LazyActivityScenarioRule.kt:60)
	at fake.package.name.MainActivityLogoutTests.setUp(MainActivityLogoutTests.kt:79)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/java.lang.reflect.Method.invoke(Unknown Source)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions