Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some tests can not mock class in Java17 #518

Open
ArpitPatel009 opened this issue Jun 13, 2024 · 0 comments
Open

Some tests can not mock class in Java17 #518

ArpitPatel009 opened this issue Jun 13, 2024 · 0 comments

Comments

@ArpitPatel009
Copy link

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant