1
0
Fork 0

Remove Mockito

master
Tiger Oakes 2020-05-28 17:43:40 -07:00 committed by Emily Kager
parent 4fac1959b1
commit f0295048fa
21 changed files with 286 additions and 288 deletions

View File

@ -593,8 +593,6 @@ dependencies {
testImplementation 'org.apache.maven:maven-ant-tasks:2.1.3'
implementation Deps.mozilla_support_rusthttp
testImplementation Deps.mockito_core
androidTestImplementation Deps.mockito_android
testImplementation Deps.mockk
// For the initial release of Glean 19, we require consumer applications to

View File

@ -32,7 +32,7 @@ class IntentReceiverActivity : Activity() {
// The intent property is nullable, but the rest of the code below
// assumes it is not. If it's null, then we make a new one and open
// the HomeActivity.
val intent = intent?.let { Intent(intent) } ?: Intent()
val intent = intent?.let { Intent(it) } ?: Intent()
intent.stripUnwantedFlags()
processIntent(intent)
}

View File

@ -18,7 +18,7 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import mozilla.components.concept.sync.DeviceCapability
import mozilla.components.feature.share.RecentAppsStorage
@ -38,6 +38,8 @@ class ShareViewModel(application: Application) : AndroidViewModel(application) {
private val fxaAccountManager = application.components.backgroundServices.accountManager
@VisibleForTesting
internal var recentAppsStorage = RecentAppsStorage(application.applicationContext)
@VisibleForTesting
internal var ioDispatcher = Dispatchers.IO
private val devicesListLiveData = MutableLiveData<List<SyncShareOption>>(emptyList())
private val appsListLiveData = MutableLiveData<List<AppShareOption>>(emptyList())
@ -49,7 +51,7 @@ class ShareViewModel(application: Application) : AndroidViewModel(application) {
override fun onAvailable(network: Network?) = reloadDevices(network)
private fun reloadDevices(network: Network?) {
viewModelScope.launch(IO) {
viewModelScope.launch(ioDispatcher) {
fxaAccountManager.authenticatedAccount()
?.deviceConstellation()
?.refreshDevicesAsync()
@ -83,7 +85,7 @@ class ShareViewModel(application: Application) : AndroidViewModel(application) {
connectivityManager?.registerNetworkCallback(networkRequest, networkCallback)
// Start preparing the data as soon as we have a valid Context
viewModelScope.launch(IO) {
viewModelScope.launch(ioDispatcher) {
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
flags = Intent.FLAG_ACTIVITY_NEW_TASK
@ -98,7 +100,7 @@ class ShareViewModel(application: Application) : AndroidViewModel(application) {
appsListLiveData.postValue(apps)
}
viewModelScope.launch(IO) {
viewModelScope.launch(ioDispatcher) {
val devices = buildDeviceList(fxaAccountManager)
devicesListLiveData.postValue(devices)
}

View File

@ -4,42 +4,63 @@
package org.mozilla.fenix
import android.app.Activity
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.feature.intent.processing.IntentProcessor
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mozilla.fenix.components.IntentProcessors
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.shortcut.NewTabShortcutIntentProcessor
import org.robolectric.Robolectric
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.shortcut.NewTabShortcutIntentProcessor
import org.mozilla.fenix.utils.Settings
import org.robolectric.Robolectric
import org.robolectric.Shadows.shadowOf
@ExperimentalCoroutinesApi
@RunWith(FenixRobolectricTestRunner::class)
class IntentReceiverActivityTest {
private lateinit var settings: Settings
private lateinit var intentProcessors: IntentProcessors
@Before
fun setup() {
settings = mockk()
intentProcessors = mockk()
every { settings.openLinksInAPrivateTab } returns false
every { intentProcessors.intentProcessor } returns mockIntentProcessor()
every { intentProcessors.privateIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.customTabIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.privateCustomTabIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.externalAppIntentProcessors } returns emptyList()
every { intentProcessors.fennecPageShortcutIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.migrationIntentProcessor } returns mockIntentProcessor()
coEvery { intentProcessors.intentProcessor.process(any()) } returns true
}
@Test
fun `process intent with flag launched from history`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = false
val intent = Intent()
intent.flags = FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.intentProcessor.process(intent)).thenReturn(true)
`when`(testContext.components.intentProcessors.customTabIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
val shadow = shadowOf(activity)
@ -51,16 +72,13 @@ class IntentReceiverActivityTest {
@Test
fun `process intent with action OPEN_PRIVATE_TAB`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = false
val intent = Intent()
intent.action = NewTabShortcutIntentProcessor.ACTION_OPEN_PRIVATE_TAB
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.intentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.customTabIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
coEvery { intentProcessors.intentProcessor.process(intent) } returns false
coEvery { intentProcessors.customTabIntentProcessor.process(intent) } returns false
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
val shadow = shadowOf(activity)
@ -73,16 +91,11 @@ class IntentReceiverActivityTest {
@Test
fun `process intent with action OPEN_TAB`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = false
val intent = Intent()
intent.action = NewTabShortcutIntentProcessor.ACTION_OPEN_TAB
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.intentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.customTabIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
val shadow = shadowOf(activity)
@ -90,19 +103,13 @@ class IntentReceiverActivityTest {
assertEquals(HomeActivity::class.java.name, actualIntent.component?.className)
assertEquals(false, actualIntent.getBooleanExtra(HomeActivity.PRIVATE_BROWSING_MODE, false))
assertEquals(false, actualIntent.getBooleanExtra(HomeActivity.OPEN_TO_BROWSER, true))
}
@Test
fun `process intent starts Activity`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = false
val intent = Intent()
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.intentProcessor.process(intent)).thenReturn(true)
`when`(testContext.components.intentProcessors.customTabIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
val shadow = shadowOf(activity)
@ -114,57 +121,45 @@ class IntentReceiverActivityTest {
@Test
fun `process intent with launchLinksInPrivateTab set to true`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = true
every { settings.openLinksInAPrivateTab } returns true
coEvery { intentProcessors.intentProcessor.process(any()) } returns false
coEvery { intentProcessors.privateIntentProcessor.process(any()) } returns true
val intent = Intent()
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.privateIntentProcessor.process(intent)).thenReturn(true)
`when`(testContext.components.intentProcessors.privateCustomTabIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
// Not using mockk here because process is a suspend function
// and mockito makes this easier to read.
verify(testContext.components.intentProcessors.intentProcessor, never()).process(intent)
verify(testContext.components.intentProcessors.privateIntentProcessor).process(intent)
val normalProcessor = intentProcessors.intentProcessor
coVerify(exactly = 0) { normalProcessor.process(intent) }
coVerify { intentProcessors.privateIntentProcessor.process(intent) }
}
@Test
fun `process intent with launchLinksInPrivateTab set to false`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = false
val intent = Intent()
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.intentProcessor.process(intent)).thenReturn(true)
`when`(testContext.components.intentProcessors.customTabIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
// Not using mockk here because process is a suspend function
// and mockito makes this easier to read.
verify(testContext.components.intentProcessors.privateIntentProcessor, never()).process(intent)
verify(testContext.components.intentProcessors.intentProcessor).process(intent)
coVerify(exactly = 0) { intentProcessors.privateIntentProcessor.process(intent) }
coVerify { intentProcessors.intentProcessor.process(intent) }
}
@Test
fun `process custom tab intent`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = false
val intent = Intent()
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.customTabIntentProcessor.process(intent)).thenReturn(true)
coEvery { intentProcessors.intentProcessor.process(intent) } returns false
coEvery { intentProcessors.customTabIntentProcessor.process(intent) } returns true
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
// Not using mockk here because process is a suspend function
// and mockito makes this easier to read.
verify(testContext.components.intentProcessors.privateIntentProcessor, never()).process(intent)
verify(testContext.components.intentProcessors.customTabIntentProcessor).process(intent)
coVerify(exactly = 0) { intentProcessors.privateCustomTabIntentProcessor.process(intent) }
coVerify { intentProcessors.customTabIntentProcessor.process(intent) }
assertEquals(ExternalAppBrowserActivity::class.java.name, intent.component!!.className)
assertTrue(intent.getBooleanExtra(HomeActivity.OPEN_TO_BROWSER, false))
@ -172,22 +167,33 @@ class IntentReceiverActivityTest {
@Test
fun `process private custom tab intent`() = runBlockingTest {
testContext.settings().openLinksInAPrivateTab = true
every { settings.openLinksInAPrivateTab } returns true
val intent = Intent()
`when`(testContext.components.intentProcessors.migrationIntentProcessor.process(intent)).thenReturn(false)
`when`(testContext.components.intentProcessors.privateCustomTabIntentProcessor.process(intent)).thenReturn(true)
`when`(testContext.components.intentProcessors.fennecPageShortcutIntentProcessor.process(intent)).thenReturn(false)
coEvery { intentProcessors.privateCustomTabIntentProcessor.process(intent) } returns true
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
// Not using mockk here because process is a suspend function
// and mockito makes this easier to read.
verify(testContext.components.intentProcessors.intentProcessor, never()).process(intent)
verify(testContext.components.intentProcessors.privateCustomTabIntentProcessor).process(intent)
val normalProcessor = intentProcessors.customTabIntentProcessor
coVerify(exactly = 0) { normalProcessor.process(intent) }
coVerify { intentProcessors.privateCustomTabIntentProcessor.process(intent) }
assertEquals(ExternalAppBrowserActivity::class.java.name, intent.component!!.className)
assertTrue(intent.getBooleanExtra(HomeActivity.OPEN_TO_BROWSER, false))
}
private fun attachMocks(activity: Activity) {
mockkStatic("org.mozilla.fenix.ext.ContextKt")
every { activity.settings() } returns settings
every { activity.components.analytics } returns mockk(relaxed = true)
every { activity.components.intentProcessors } returns intentProcessors
}
private inline fun <reified T : IntentProcessor> mockIntentProcessor(): T {
return mockk {
coEvery { process(any()) } returns false
}
}
}

View File

@ -4,27 +4,26 @@
package org.mozilla.fenix.components
import io.mockk.Called
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.runBlocking
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.service.fxa.manager.FxaAccountManager
import mozilla.components.support.test.argumentCaptor
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.verify
import kotlin.reflect.KClass
@RunWith(FenixRobolectricTestRunner::class)
class AccountAbnormalitiesTest {
@Test
fun `account manager must be configured`() {
val crashReporter: CrashReporter = mock()
val crashReporter: CrashReporter = mockk()
// no account present
val accountAbnormalities = AccountAbnormalities(testContext, crashReporter)
@ -37,7 +36,7 @@ class AccountAbnormalitiesTest {
}
try {
accountAbnormalities.onAuthenticated(mock(), mock())
accountAbnormalities.onAuthenticated(mockk(), mockk())
fail()
} catch (e: IllegalStateException) {
assertEquals("onAuthenticated before account manager was configured", e.message)
@ -50,13 +49,13 @@ class AccountAbnormalitiesTest {
assertEquals("onLoggedOut before account manager was configured", e.message)
}
verifyZeroInteractions(crashReporter)
verify { crashReporter wasNot Called }
}
@Test
fun `LogoutWithoutAuth detected`() = runBlocking {
val crashReporter: CrashReporter = mock()
val accountManager: FxaAccountManager = mock()
val crashReporter: CrashReporter = mockk(relaxed = true)
val accountManager: FxaAccountManager = mockk(relaxed = true)
val accountAbnormalities = AccountAbnormalities(testContext, crashReporter, this.coroutineContext)
accountAbnormalities.accountManagerInitializedAsync(
@ -66,13 +65,13 @@ class AccountAbnormalitiesTest {
// Logout action must be preceded by auth.
accountAbnormalities.userRequestedLogout()
assertCaughtException(crashReporter, AbnormalFxaEvent.LogoutWithoutAuth::class)
assertCaughtException<AbnormalFxaEvent.LogoutWithoutAuth>(crashReporter)
}
@Test
fun `OverlappingFxaLogoutRequest detected`() = runBlocking {
val crashReporter: CrashReporter = mock()
val accountManager: FxaAccountManager = mock()
val crashReporter: CrashReporter = mockk(relaxed = true)
val accountManager: FxaAccountManager = mockk(relaxed = true)
val accountAbnormalities = AccountAbnormalities(testContext, crashReporter, this.coroutineContext)
accountAbnormalities.accountManagerInitializedAsync(
@ -80,20 +79,20 @@ class AccountAbnormalitiesTest {
CompletableDeferred(Unit).also { it.complete(Unit) }
).await()
accountAbnormalities.onAuthenticated(mock(), mock())
accountAbnormalities.onAuthenticated(mockk(), mockk())
// So far, so good. A regular logout request while being authenticated.
accountAbnormalities.userRequestedLogout()
verifyZeroInteractions(crashReporter)
verify { crashReporter wasNot Called }
// We never saw a logout callback after previous logout request, so this is an overlapping request.
accountAbnormalities.userRequestedLogout()
assertCaughtException(crashReporter, AbnormalFxaEvent.OverlappingFxaLogoutRequest::class)
assertCaughtException<AbnormalFxaEvent.OverlappingFxaLogoutRequest>(crashReporter)
}
@Test
fun `callback logout abnormalities detected`() = runBlocking {
val crashReporter: CrashReporter = mock()
val accountManager: FxaAccountManager = mock()
val crashReporter: CrashReporter = mockk(relaxed = true)
val accountManager: FxaAccountManager = mockk(relaxed = true)
val accountAbnormalities = AccountAbnormalities(testContext, crashReporter, this.coroutineContext)
accountAbnormalities.accountManagerInitializedAsync(
@ -103,13 +102,13 @@ class AccountAbnormalitiesTest {
// User didn't request this logout.
accountAbnormalities.onLoggedOut()
assertCaughtException(crashReporter, AbnormalFxaEvent.UnexpectedFxaLogout::class)
assertCaughtException<AbnormalFxaEvent.UnexpectedFxaLogout>(crashReporter)
}
@Test
fun `login happy case + disappearing account detected`() = runBlocking {
val crashReporter: CrashReporter = mock()
val accountManager: FxaAccountManager = mock()
val crashReporter: CrashReporter = mockk(relaxed = true)
val accountManager: FxaAccountManager = mockk(relaxed = true)
val accountAbnormalities = AccountAbnormalities(testContext, crashReporter, this.coroutineContext)
accountAbnormalities.accountManagerInitializedAsync(
@ -117,8 +116,9 @@ class AccountAbnormalitiesTest {
CompletableDeferred(Unit).also { it.complete(Unit) }
).await()
accountAbnormalities.onAuthenticated(mock(), mock())
verifyZeroInteractions(crashReporter)
accountAbnormalities.onAuthenticated(mockk(), mockk())
verify { crashReporter wasNot Called }
every { accountManager.authenticatedAccount() } returns null
// Pretend we restart, and instantiate a new middleware instance.
val accountAbnormalities2 = AccountAbnormalities(testContext, crashReporter, this.coroutineContext)
@ -129,13 +129,13 @@ class AccountAbnormalitiesTest {
CompletableDeferred(Unit).also { it.complete(Unit) }
).await()
assertCaughtException(crashReporter, AbnormalFxaEvent.MissingExpectedAccountAfterStartup::class)
assertCaughtException<AbnormalFxaEvent.MissingExpectedAccountAfterStartup>(crashReporter)
}
@Test
fun `logout happy case`() = runBlocking {
val crashReporter: CrashReporter = mock()
val accountManager: FxaAccountManager = mock()
val crashReporter: CrashReporter = mockk()
val accountManager: FxaAccountManager = mockk(relaxed = true)
val accountAbnormalities = AccountAbnormalities(testContext, crashReporter, this.coroutineContext)
accountAbnormalities.accountManagerInitializedAsync(
@ -144,14 +144,14 @@ class AccountAbnormalitiesTest {
).await()
// We saw an auth event, then user requested a logout.
accountAbnormalities.onAuthenticated(mock(), mock())
accountAbnormalities.onAuthenticated(mockk(), mockk())
accountAbnormalities.userRequestedLogout()
verifyZeroInteractions(crashReporter)
verify { crashReporter wasNot Called }
}
private fun <T : AbnormalFxaEvent> assertCaughtException(crashReporter: CrashReporter, type: KClass<T>) {
val captor = argumentCaptor<AbnormalFxaEvent>()
verify(crashReporter).submitCaughtException(captor.capture())
assertEquals(type, captor.value::class)
private inline fun <reified T : AbnormalFxaEvent> assertCaughtException(crashReporter: CrashReporter) {
verify {
crashReporter.submitCaughtException(any<T>())
}
}
}

View File

@ -2,76 +2,74 @@ package org.mozilla.fenix.components
import android.view.View
import android.view.ViewStub
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import org.junit.Test
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import java.lang.ref.WeakReference
class InflationAwareFeatureTest {
@Test
fun `stub inflates if no feature or view exists`() {
val stub: ViewStub = mock()
val feature: InflationAwareFeature = spy(TestableInflationAwareFeature(stub))
val stub: ViewStub = mockk(relaxed = true)
val feature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
feature.launch()
verify(stub).setOnInflateListener(any())
verify(stub).inflate()
verify { stub.setOnInflateListener(any()) }
verify { stub.inflate() }
}
@Test
fun `stub immediately launches if the feature is available`() {
val stub: ViewStub = mock()
val feature: InflationAwareFeature = spy(TestableInflationAwareFeature(stub))
val stub: ViewStub = mockk()
val feature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
feature.feature = mock()
feature.view = WeakReference(mock())
feature.feature = mockk(relaxed = true)
feature.view = WeakReference(mockk())
feature.launch()
verify(stub, never()).setOnInflateListener(any())
verify(stub, never()).inflate()
verify(feature).onLaunch(any(), any())
verify(exactly = 0) { stub.setOnInflateListener(any()) }
verify(exactly = 0) { stub.inflate() }
verify { feature.onLaunch(any(), any()) }
}
@Test
fun `feature calls stop if created`() {
val stub: ViewStub = mock()
val inflationFeature: InflationAwareFeature = spy(TestableInflationAwareFeature(stub))
val innerFeature: LifecycleAwareFeature = mock()
val stub: ViewStub = mockk()
val inflationFeature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
val innerFeature: LifecycleAwareFeature = mockk(relaxed = true)
inflationFeature.stop()
verify(innerFeature, never()).stop()
verify(exactly = 0) { innerFeature.stop() }
inflationFeature.feature = innerFeature
inflationFeature.stop()
verify(innerFeature).stop()
verify { innerFeature.stop() }
}
@Test
fun `start should be delegated to the inner feature`() {
val inflationFeature: InflationAwareFeature = spy(TestableInflationAwareFeature(mock()))
val innerFeature: LifecycleAwareFeature = mock()
val inflationFeature: InflationAwareFeature = spyk(TestableInflationAwareFeature(mockk()))
val innerFeature: LifecycleAwareFeature = mockk(relaxed = true)
inflationFeature.feature = innerFeature
inflationFeature.start()
verify(innerFeature).start()
verify { innerFeature.start() }
}
@Test
fun `if feature has implemented UserInteractionHandler invoke it`() {
val stub: ViewStub = mock()
val inflationFeature: InflationAwareFeature = spy(TestableInflationAwareFeature(stub))
val innerFeature: LifecycleAwareFeature = mock()
val stub: ViewStub = mockk()
val inflationFeature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
val innerFeature: LifecycleAwareFeature = mockk()
val userInteractionHandlerFeature = object : LifecycleAwareFeature, UserInteractionHandler {
override fun onBackPressed() = true
@ -93,10 +91,7 @@ class InflationAwareFeatureTest {
}
class TestableInflationAwareFeature(stub: ViewStub) : InflationAwareFeature(stub) {
override fun onViewInflated(view: View): LifecycleAwareFeature {
return mock()
}
override fun onViewInflated(view: View): LifecycleAwareFeature = mockk()
override fun onLaunch(view: View, feature: LifecycleAwareFeature) {
}
override fun onLaunch(view: View, feature: LifecycleAwareFeature) = Unit
}

View File

@ -6,8 +6,6 @@ package org.mozilla.fenix.components
import android.content.Context
import io.mockk.mockk
import mozilla.components.support.test.mock
import org.mockito.Mockito.`when`
import org.mozilla.fenix.utils.ClipboardHandler
class TestComponents(private val context: Context) : Components(context) {
@ -28,17 +26,7 @@ class TestComponents(private val context: Context) : Components(context) {
core.thumbnailStorage
)
}
override val intentProcessors by lazy {
val processors: IntentProcessors = mock()
`when`(processors.externalAppIntentProcessors).thenReturn(emptyList())
`when`(processors.privateIntentProcessor).thenReturn(mock())
`when`(processors.intentProcessor).thenReturn(mock())
`when`(processors.customTabIntentProcessor).thenReturn(mock())
`when`(processors.privateCustomTabIntentProcessor).thenReturn(mock())
`when`(processors.migrationIntentProcessor).thenReturn(mock())
`when`(processors.fennecPageShortcutIntentProcessor).thenReturn(mock())
processors
}
override val intentProcessors by lazy { mockk<IntentProcessors>(relaxed = true) }
override val analytics by lazy { Analytics(context) }
override val clipboardHandler by lazy { ClipboardHandler(context) }

View File

@ -6,17 +6,17 @@ package org.mozilla.fenix.components.metrics
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.lib.crash.Crash
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.crash.service.CrashReporterService
import mozilla.components.support.base.crash.Breadcrumb
import mozilla.components.support.test.any
import mozilla.components.support.test.mock
import org.junit.Test
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
internal class BreadcrumbRecorderTest {
@Test
fun `ensure crash reporter recordCrashBreadcrumb is called`() {
val service = object : CrashReporterService {
@ -28,9 +28,9 @@ internal class BreadcrumbRecorderTest {
override fun report(crash: Crash.UncaughtExceptionCrash): String? = ""
}
val reporter = spy(
val reporter = spyk(
CrashReporter(
context = mock(),
context = mockk(),
services = listOf(service),
shouldPrompt = CrashReporter.Prompt.NEVER
)
@ -40,13 +40,13 @@ internal class BreadcrumbRecorderTest {
return "test"
}
val navController: NavController = mock()
val navDestination: NavDestination = mock()
val navController: NavController = mockk()
val navDestination: NavDestination = mockk()
val breadCrumbRecorder =
BreadcrumbsRecorder(reporter, navController, ::getBreadcrumbMessage)
breadCrumbRecorder.onDestinationChanged(navController, navDestination, null)
verify(reporter).recordCrashBreadcrumb(any())
verify { reporter.recordCrashBreadcrumb(any()) }
}
}

View File

@ -10,24 +10,24 @@ import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.mockkStatic
import io.mockk.slot
import io.mockk.unmockkStatic
import kotlinx.coroutines.runBlocking
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Ignore
import org.junit.Assert.assertNull
import org.junit.Test
import org.mockito.ArgumentMatchers
import java.io.IOException
class MetricsUtilsTest {
private val context: Context = mockk(relaxed = true)
@Ignore("This test has side-effects that cause it to fail other unrelated tests.")
@Test
fun `getAdvertisingID() returns null if the API throws`() {
mockkStatic("com.google.android.gms.ads.identifier.AdvertisingIdClient")
val exceptions = listOf(
GooglePlayServicesNotAvailableException(1),
GooglePlayServicesRepairableException(0, ArgumentMatchers.anyString(), ArgumentMatchers.any()),
GooglePlayServicesRepairableException(0, "", mockk()),
IllegalStateException(),
IOException()
)
@ -37,8 +37,10 @@ class MetricsUtilsTest {
AdvertisingIdClient.getAdvertisingIdInfo(any())
} throws it
Assert.assertNull(MetricsUtils.getAdvertisingID(context))
assertNull(MetricsUtils.getAdvertisingID(context))
}
unmockkStatic("com.google.android.gms.ads.identifier.AdvertisingIdClient")
}
@Test
@ -46,7 +48,7 @@ class MetricsUtilsTest {
mockkStatic(AdvertisingIdClient::class)
every { AdvertisingIdClient.getAdvertisingIdInfo(any()) } returns null
Assert.assertNull(MetricsUtils.getAdvertisingID(context))
assertNull(MetricsUtils.getAdvertisingID(context))
}
@Test

View File

@ -1,7 +1,8 @@
package org.mozilla.fenix.components.searchengine
import android.content.Context
import android.graphics.Bitmap
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -15,8 +16,6 @@ import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ExperimentalCoroutinesApi
@ -115,11 +114,10 @@ class FakeFenixSearchEngineProvider(context: Context) : FenixSearchEngineProvide
id: String,
n: String = id
): SearchEngine {
// Uses Mockito because of a strange Mockk error. Feel free to rewrite
return mock(SearchEngine::class.java).apply {
`when`(identifier).thenReturn(id)
`when`(name).thenReturn(n)
`when`(icon).thenReturn(mock(Bitmap::class.java))
}
val engine = mockk<SearchEngine>()
every { engine.identifier } returns id
every { engine.name } returns n
every { engine.icon } returns mockk()
return engine
}
}

View File

@ -9,14 +9,13 @@ import android.os.Bundle
import androidx.navigation.NavDirections
import io.mockk.every
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.support.utils.toSafeIntent
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Test
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.components.metrics.Event
@ -40,7 +39,7 @@ class ExternalAppBrowserActivityTest {
@Test
fun `getNavDirections finishes activity if session ID is null`() {
val activity = spy(object : ExternalAppBrowserActivity() {
val activity = spyk(object : ExternalAppBrowserActivity() {
public override fun getNavDirections(
from: BrowserDirection,
customTabSessionId: String?
@ -59,10 +58,10 @@ class ExternalAppBrowserActivityTest {
var directions = activity.getNavDirections(BrowserDirection.FromGlobal, "id")
assertNotNull(directions)
verify(activity, never()).finish()
verify(exactly = 0) { activity.finish() }
directions = activity.getNavDirections(BrowserDirection.FromGlobal, null)
assertNull(directions)
verify(activity).finish()
verify { activity.finish() }
}
}

View File

@ -4,12 +4,12 @@
package org.mozilla.fenix.customtabs
import io.mockk.mockk
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.CustomTabConfig
import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.browser.state.state.createCustomTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import org.junit.Test
import org.junit.runner.RunWith
@ -50,7 +50,7 @@ class PoweredByNotificationTest {
@Test
fun `unregister receiver on pause`() {
val feature = PoweredByNotification(testContext, mock(), "session-id")
val feature = PoweredByNotification(testContext, mockk(), "session-id")
feature.onPause()
}
}

View File

@ -7,16 +7,15 @@ package org.mozilla.fenix.downloads
import android.animation.ValueAnimator
import android.view.View
import androidx.core.view.ViewCompat
import mozilla.components.support.test.mock
import io.mockk.every
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.never
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
@ -24,24 +23,24 @@ class DynamicDownloadDialogBehaviorTest {
@Test
fun `Starting a nested scroll should cancel an ongoing snap animation`() {
val behavior = spy(DynamicDownloadDialogBehavior<View>(testContext, attrs = null))
doReturn(true).`when`(behavior).shouldScroll
val behavior = spyk(DynamicDownloadDialogBehavior<View>(testContext, attrs = null))
every { behavior.shouldScroll } returns true
val animator: ValueAnimator = mock()
val animator: ValueAnimator = mockk(relaxed = true)
behavior.snapAnimator = animator
val acceptsNestedScroll = behavior.onStartNestedScroll(
coordinatorLayout = mock(),
child = mock(),
directTargetChild = mock(),
target = mock(),
coordinatorLayout = mockk(),
child = mockk(),
directTargetChild = mockk(),
target = mockk(),
axes = ViewCompat.SCROLL_AXIS_VERTICAL,
type = ViewCompat.TYPE_TOUCH
)
assertTrue(acceptsNestedScroll)
verify(animator).cancel()
verify { animator.cancel() }
}
@Test
@ -49,10 +48,10 @@ class DynamicDownloadDialogBehaviorTest {
val behavior = DynamicDownloadDialogBehavior<View>(testContext, attrs = null)
val acceptsNestedScroll = behavior.onStartNestedScroll(
coordinatorLayout = mock(),
child = mock(),
directTargetChild = mock(),
target = mock(),
coordinatorLayout = mockk(),
child = mockk(),
directTargetChild = mockk(),
target = mockk(),
axes = ViewCompat.SCROLL_AXIS_HORIZONTAL,
type = ViewCompat.TYPE_TOUCH
)
@ -62,117 +61,123 @@ class DynamicDownloadDialogBehaviorTest {
@Test
fun `Behavior will snap the dialog up if it is more than 50% visible`() {
val behavior = spy(DynamicDownloadDialogBehavior<View>(testContext, attrs = null,
val behavior = spyk(DynamicDownloadDialogBehavior<View>(testContext, attrs = null,
bottomToolbarHeight = 10f))
doReturn(true).`when`(behavior).shouldScroll
every { behavior.shouldScroll } returns true
val animator: ValueAnimator = mock()
val animator: ValueAnimator = mockk(relaxed = true)
behavior.snapAnimator = animator
behavior.expanded = false
val child = mock<View>()
doReturn(100).`when`(child)?.height
doReturn(59f).`when`(child)?.translationY
val child = mockk<View> {
every { height } returns 100
every { translationY } returns 59f
}
behavior.onStartNestedScroll(
coordinatorLayout = mock(),
coordinatorLayout = mockk(),
child = child,
directTargetChild = mock(),
target = mock(),
directTargetChild = mockk(),
target = mockk(),
axes = ViewCompat.SCROLL_AXIS_VERTICAL,
type = ViewCompat.TYPE_TOUCH
)
assertTrue(behavior.shouldSnapAfterScroll)
verify(animator, never()).start()
verify(exactly = 0) { animator.start() }
behavior.onStopNestedScroll(
coordinatorLayout = mock(),
coordinatorLayout = mockk(),
child = child,
target = mock(),
target = mockk(),
type = 0
)
verify(behavior).animateSnap(child, DynamicDownloadDialogBehavior.SnapDirection.UP)
verify { behavior.animateSnap(child, DynamicDownloadDialogBehavior.SnapDirection.UP) }
verify(animator).start()
verify { animator.start() }
}
@Test
fun `Behavior will snap the dialog down if translationY is at least equal to half the toolbarHeight`() {
val behavior = spy(DynamicDownloadDialogBehavior<View>(testContext, attrs = null,
val behavior = spyk(DynamicDownloadDialogBehavior<View>(testContext, attrs = null,
bottomToolbarHeight = 10f))
doReturn(true).`when`(behavior).shouldScroll
every { behavior.shouldScroll } returns true
val animator: ValueAnimator = mock()
val animator: ValueAnimator = mockk(relaxed = true)
behavior.snapAnimator = animator
behavior.expanded = true
val child = mock<View>()
doReturn(100).`when`(child).height
doReturn(5f).`when`(child).translationY
val child = mockk<View> {
every { height } returns 100
every { translationY } returns 5f
}
behavior.onStartNestedScroll(
coordinatorLayout = mock(),
coordinatorLayout = mockk(),
child = child,
directTargetChild = mock(),
target = mock(),
directTargetChild = mockk(),
target = mockk(),
axes = ViewCompat.SCROLL_AXIS_VERTICAL,
type = ViewCompat.TYPE_TOUCH
)
assertTrue(behavior.shouldSnapAfterScroll)
verify(animator, never()).start()
verify(exactly = 0) { animator.start() }
behavior.onStopNestedScroll(
coordinatorLayout = mock(),
coordinatorLayout = mockk(),
child = child,
target = mock(),
target = mockk(),
type = 0
)
verify(behavior).animateSnap(child, DynamicDownloadDialogBehavior.SnapDirection.DOWN)
verify { behavior.animateSnap(child, DynamicDownloadDialogBehavior.SnapDirection.DOWN) }
verify(animator).start()
verify { animator.start() }
}
@Test
fun `Behavior will apply translation to the dialog for nested scroll`() {
val behavior = spy(DynamicDownloadDialogBehavior<View>(testContext, attrs = null))
doReturn(true).`when`(behavior).shouldScroll
val behavior = spyk(DynamicDownloadDialogBehavior<View>(testContext, attrs = null))
every { behavior.shouldScroll } returns true
val child = mock<View>()
doReturn(100).`when`(child).height
doReturn(0f).`when`(child).translationY
val child = mockk<View> {
every { height } returns 100
every { translationY } returns 0f
every { translationY = any() } returns Unit
}
behavior.onNestedPreScroll(
coordinatorLayout = mock(),
coordinatorLayout = mockk(),
child = child,
target = mock(),
target = mockk(),
dx = 0,
dy = 25,
consumed = IntArray(0),
type = 0
)
verify(child).translationY = 25f
verify { child.translationY = 25f }
}
@Test
fun `Behavior will animateSnap UP when forceExpand is called`() {
val behavior = spy(DynamicDownloadDialogBehavior<View>(testContext, attrs = null))
val dynamicDialogView: View = mock()
doReturn(true).`when`(behavior).shouldScroll
val behavior = spyk(DynamicDownloadDialogBehavior<View>(testContext, attrs = null))
val dynamicDialogView: View = mockk(relaxed = true)
every { behavior.shouldScroll } returns true
behavior.forceExpand(dynamicDialogView)
verify(behavior).animateSnap(
dynamicDialogView,
DynamicDownloadDialogBehavior.SnapDirection.UP
)
verify {
behavior.animateSnap(
dynamicDialogView,
DynamicDownloadDialogBehavior.SnapDirection.UP
)
}
}
}

View File

@ -4,12 +4,13 @@
package org.mozilla.fenix.ext
import io.mockk.mockk
import mozilla.components.browser.session.Session
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.ReaderState
import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.support.test.mock
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
@ -36,8 +37,9 @@ class SessionTest {
val tabs = listOf(tabWithoutReaderState, tabWithInactiveReaderState, tabWithActiveReaderState)
val store = BrowserStore(BrowserState(tabs))
assertEquals(sessionWithoutReaderState.url, sessionWithoutReaderState.toTab(store, mock()).url)
assertEquals(sessionWithInactiveReaderState.url, sessionWithInactiveReaderState.toTab(store, mock()).url)
assertEquals("https://blog.mozilla.org/123", sessionWithActiveReaderState.toTab(store, mock()).url)
val suffixList = mockk<PublicSuffixList>(relaxed = true)
assertEquals(sessionWithoutReaderState.url, sessionWithoutReaderState.toTab(store, suffixList).url)
assertEquals(sessionWithInactiveReaderState.url, sessionWithInactiveReaderState.toTab(store, suffixList).url)
assertEquals("https://blog.mozilla.org/123", sessionWithActiveReaderState.toTab(store, suffixList).url)
}
}

View File

@ -5,14 +5,14 @@
package org.mozilla.fenix.ext
import androidx.core.content.ContextCompat
import io.mockk.every
import io.mockk.mockk
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -33,8 +33,8 @@ class TabCollectionTest {
}
private fun mockTabCollection(id: Long): TabCollection {
val collection: TabCollection = mock()
`when`(collection.id).thenReturn(id)
val collection: TabCollection = mockk()
every { collection.id } returns id
return collection
}
}

View File

@ -10,14 +10,16 @@ import io.mockk.Called
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import mozilla.components.browser.search.SearchEngine
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.widget.VoiceSearchActivity.Companion.SPEECH_PROCESSING
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.widget.VoiceSearchActivity.Companion.SPEECH_PROCESSING
@RunWith(FenixRobolectricTestRunner::class)
class SpeechProcessingIntentProcessorTest {
@ -27,6 +29,13 @@ class SpeechProcessingIntentProcessorTest {
private val out: Intent = mockk(relaxed = true)
private val metrics: MetricController = mockk(relaxed = true)
@Before
fun setup() {
val searchEngine = mockk<SearchEngine>(relaxed = true)
every { activity.components.search.searchEngineManager.defaultSearchEngine } returns searchEngine
every { activity.components.search.provider.getDefaultEngine(activity) } returns searchEngine
}
@Test
fun `do not process blank intents`() {
val processor = SpeechProcessingIntentProcessor(activity, metrics)
@ -58,7 +67,6 @@ class SpeechProcessingIntentProcessorTest {
putExtra(HomeActivity.OPEN_TO_BROWSER_AND_LOAD, true)
}
val processor = SpeechProcessingIntentProcessor(activity, metrics)
every { activity.components.search.provider.getDefaultEngine(activity) } returns mockk(relaxed = true)
processor.process(intent, navController, out)
@ -81,7 +89,6 @@ class SpeechProcessingIntentProcessorTest {
putExtra(SPEECH_PROCESSING, "hello world")
}
val processor = SpeechProcessingIntentProcessor(activity, metrics)
every { activity.components.search.provider.getDefaultEngine(activity) } returns mockk(relaxed = true)
processor.process(intent, mockk(), mockk(relaxed = true))

View File

@ -20,6 +20,7 @@ import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -182,8 +183,8 @@ class HistoryControllerTest {
}
assertEquals(
directions.captured::class.simpleName,
"ActionGlobalShareFragment"
directions.captured.actionId,
R.id.action_global_shareFragment
)
assertEquals(1, (directions.captured.arguments["data"] as Array<ShareData>).size)
assertEquals(historyItem.title, (directions.captured.arguments["data"] as Array<ShareData>)[0].title)

View File

@ -14,7 +14,6 @@ import io.mockk.mockkObject
import io.mockk.mockkStatic
import io.mockk.verify
import mozilla.components.support.locale.LocaleManager
import mozilla.components.support.test.mock
import org.junit.Before
import org.junit.Test
import java.util.Locale
@ -61,7 +60,7 @@ class LocaleSettingsControllerTest {
@Test
fun `set a new locale from the list`() {
val selectedLocale = Locale("en", "UK")
val otherLocale: Locale = mock()
val otherLocale: Locale = mockk()
every { localeSettingsStore.state } returns LocaleSettingsState(
mockk(),
mockk(),

View File

@ -11,6 +11,7 @@ import android.content.pm.ResolveInfo
import android.graphics.drawable.Drawable
import android.net.ConnectivityManager
import androidx.core.content.getSystemService
import androidx.lifecycle.asFlow
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
@ -18,8 +19,8 @@ import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.runBlockingTest
import mozilla.components.feature.share.RecentApp
@ -33,21 +34,23 @@ import org.junit.runner.RunWith
import org.mozilla.fenix.ext.application
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.isOnline
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.share.ShareViewModel.Companion.RECENT_APPS_LIMIT
import org.mozilla.fenix.share.listadapters.AppShareOption
import org.mozilla.fenix.share.listadapters.SyncShareOption
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
@ExperimentalCoroutinesApi
class ShareViewModelTest {
private val packageName = "org.mozilla.fenix"
private val testIoDispatcher = TestCoroutineDispatcher()
private lateinit var application: Application
private lateinit var packageManager: PackageManager
private lateinit var connectivityManager: ConnectivityManager
private lateinit var fxaAccountManager: FxaAccountManager
private lateinit var viewModel: ShareViewModel
private lateinit var storage: RecentAppsStorage
@Before
fun setup() {
@ -55,6 +58,7 @@ class ShareViewModelTest {
packageManager = mockk(relaxed = true)
connectivityManager = mockk(relaxed = true)
fxaAccountManager = mockk(relaxed = true)
storage = mockk(relaxUnitFun = true)
mockkStatic("org.mozilla.fenix.ext.ConnectivityManagerKt")
@ -63,7 +67,8 @@ class ShareViewModelTest {
every { application.getSystemService<ConnectivityManager>() } returns connectivityManager
every { application.components.backgroundServices.accountManager } returns fxaAccountManager
viewModel = ShareViewModel(application)
viewModel = spyk(ShareViewModel(application))
viewModel.ioDispatcher = testIoDispatcher
}
@Test
@ -73,28 +78,20 @@ class ShareViewModelTest {
}
@Test
fun `loadDevicesAndApps`() = runBlockingTest {
mockkStatic(Dispatchers::class)
every {
Dispatchers.IO
} returns TestCoroutineDispatcher()
viewModel = spyk(viewModel)
val drawable: Drawable = mockk()
val appOptions = ArrayList<AppShareOption>()
val appElement = AppShareOption("Label", drawable, "Package", "Activity")
appOptions.add(appElement)
fun `test loadDevicesAndApps`() = runBlockingTest {
val appOptions = listOf(
AppShareOption("Label", mockk(), "Package", "Activity")
)
val recentAppOptions = ArrayList<RecentApp>()
val appEntity: RecentApp = mockk()
val appEntity = mockk<RecentApp>()
every { appEntity.activityName } returns "Activity"
recentAppOptions.add(appEntity)
val storage: RecentAppsStorage = mockk(relaxed = true)
viewModel.recentAppsStorage = storage
every { viewModel.buildAppsList(any(), any()) } returns appOptions
val recentAppOptions = listOf(appEntity)
every { storage.updateDatabaseWithNewApps(appOptions.map { app -> app.packageName }) } just Runs
every { storage.getRecentAppsUpTo(RECENT_APPS_LIMIT) } returns recentAppOptions
every { viewModel.buildAppsList(any(), any()) } returns appOptions
viewModel.recentAppsStorage = storage
viewModel.loadDevicesAndApps()
verify {
@ -103,8 +100,8 @@ class ShareViewModelTest {
any<ConnectivityManager.NetworkCallback>()
)
}
assertEquals(1, viewModel.recentAppsList.value?.size)
assertEquals(0, viewModel.appsList.value?.size)
assertEquals(1, viewModel.recentAppsList.asFlow().first().size)
assertEquals(0, viewModel.appsList.asFlow().first().size)
}
@Test

View File

@ -6,14 +6,16 @@ package org.mozilla.fenix.tabtray
import android.view.LayoutInflater
import androidx.test.core.app.ApplicationProvider
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.spyk
import mozilla.components.browser.toolbar.MAX_URI_LENGTH
import mozilla.components.concept.tabstray.Tab
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.spy
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -25,8 +27,8 @@ class TabTrayViewHolderTest {
val view = LayoutInflater.from(ApplicationProvider.getApplicationContext()).inflate(
R.layout.tab_tray_item, null, false)
val tabViewHolder = spy(TabTrayViewHolder(view) { null })
doNothing().`when`(tabViewHolder).updateBackgroundColor(false)
val tabViewHolder = spyk(TabTrayViewHolder(view) { null })
every { tabViewHolder.updateBackgroundColor(false) } just Runs
val extremelyLongUrl = "m".repeat(MAX_URI_LENGTH + 1)
val tab = Tab(

View File

@ -37,7 +37,6 @@ object Versions {
const val installreferrer = "1.0"
const val junit = "5.5.2"
const val mockito = "2.24.5"
const val mockk = "1.10.0"
const val mockwebserver = "3.11.0"
@ -176,8 +175,6 @@ object Deps {
const val installreferrer = "com.android.installreferrer:installreferrer:${Versions.installreferrer}"
const val junit = "junit:junit:${Versions.junit}"
const val mockito_core = "org.mockito:mockito-core:${Versions.mockito}"
const val mockito_android = "org.mockito:mockito-android:${Versions.mockito}"
const val mockk = "io.mockk:mockk:${Versions.mockk}"
// --- START AndroidX test dependencies --- //