Skip to content

Commit

Permalink
[Android] Adds dexmaker to mock classes during Instrumented Tests
Browse files Browse the repository at this point in the history
To have the SDK we must move the tests from unit to Instrumented Tests
as unit tests aren't able to load our compiled SDK since the target
mismatches (Unit tests require linux-x86-64).

Mockito isn't able to mock final classes and instead of making all of
them open, we can use dexmaker to proxy the classes and be able to
fully mock final classes.

This commit introduces dexmaker as a dependency and also overrides
dexmaker mockito-core with a more updated one.
  • Loading branch information
mup committed Feb 5, 2025
1 parent e0ec718 commit cf65d58
Show file tree
Hide file tree
Showing 13 changed files with 3,989 additions and 32 deletions.
6 changes: 5 additions & 1 deletion app-android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,15 @@ dependencies {
// JVM-based unit tests (that don't need a real device or emulator)
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"

androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito-inline-extended:2.28.1") {
exclude group: 'org.mockito', module: 'mockito-core'
}
androidTestImplementation "org.mockito:mockito-core:5.15.2"
androidTestImplementation "org.mockito.kotlin:mockito-kotlin:5.4.0"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation 'androidx.test:runner:1.6.1'
androidTestImplementation 'androidx.test.ext:junit-ktx:1.2.1'
androidTestImplementation 'androidx.test:rules:1.6.1'
androidTestImplementation 'org.mockito:mockito-android:5.12.0'
androidTestImplementation 'com.fasterxml.jackson.core:jackson-databind:2.17.2'
androidTestImplementation 'androidx.room:room-testing:2.6.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,20 @@ import de.tutao.tutashared.push.SseStorage
import de.tutao.tutashared.toBase64
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito
import org.mockito.invocation.InvocationOnMock
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.stubbing.Answer
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.ConscryptMode
import java.security.KeyStoreException
import java.security.UnrecoverableEntryException
import java.util.Calendar
import java.util.Date
import java.util.concurrent.TimeUnit

@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE)
@ConscryptMode(ConscryptMode.Mode.OFF)
class AlarmNotificationsManagerTest {

class AlarmNotificationsManagerTest {
private lateinit var manager: AlarmNotificationsManager

private lateinit var systemAlarmFacade: SystemAlarmFacade
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import android.util.Log
import de.tutao.tutanota.BuildConfig
import java.util.Date


class SystemAlarmFacade(private val context: Context) {
fun scheduleAlarmOccurrenceWithSystem(
alarmTime: Date,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ private const val ALARM_NOTIFICATION_CHANNEL_ID = "alarms"
private const val DOWNLOAD_NOTIFICATION_CHANNEL_ID = "downloads"
private const val EMAIL_ADDRESS_EXTRA = "email_address"


class LocalNotificationsFacade(private val context: Context, private val sseStorage: SseStorage) {
companion object {
private const val TAG = "LocalNotifications"
Expand Down
12 changes: 8 additions & 4 deletions app-android/calendar/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import com.android.build.gradle.internal.tasks.FinalizeBundleTask
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.gradle.configurationcache.extensions.capitalized

plugins {
id("com.android.application")
Expand Down Expand Up @@ -98,10 +98,10 @@ android {
val taskName = StringBuilder("sign").run {
//Add a task to rename the output file
productFlavors.forEach {
append(it.name.capitalizeAsciiOnly())
append(it.name.capitalized())
}

append(buildType.name.capitalizeAsciiOnly())
append(buildType.name.capitalized())
append("Bundle")

toString()
Expand Down Expand Up @@ -208,11 +208,15 @@ dependencies {
// JVM-based unit tests (that don't need a real device or emulator)
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version")

androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito-inline-extended:2.28.1") {
exclude(group = "org.mockito", module = "mockito-core")
}
androidTestImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
androidTestImplementation("org.mockito:mockito-core:5.15.2")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
androidTestImplementation("androidx.test:runner:1.4.0")
androidTestImplementation("androidx.test.ext:junit-ktx:1.1.3")
androidTestImplementation("androidx.test:rules:1.4.0")
androidTestImplementation("org.mockito:mockito-android:5.11.0")
androidTestImplementation("com.fasterxml.jackson.core:jackson-databind:2.15.2")
androidTestImplementation("androidx.room:room-testing:2.4.2")
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AlarmModelTest {
val eventStart = getDate(timeZone, 2019, 4, 2, 12, 0)
iterateAlarmOccurrences(
now, timeZone, eventStart, eventStart, RepeatPeriod.WEEKLY,
1, EndType.NEVER, 0, AlarmInterval(AlarmIntervalUnit.HOUR, 1), timeZone, emptyList()
1, EndType.NEVER, 0, AlarmInterval(AlarmIntervalUnit.HOUR, 1), timeZone, emptyList(), emptyList()
) { time: Date, _: Int, _: Date? -> occurrences.add(time) }
Assert.assertArrayEquals(
listOf(
Expand All @@ -45,8 +45,18 @@ class AlarmModelTest {
val eventEnd = getAllDayDateUTC(getDate(timeZone, 2019, 4, 3, 0, 0), timeZone)
val repeatEnd = getAllDayDateUTC(getDate(timeZone, 2019, 4, 4, 0, 0), timeZone)
iterateAlarmOccurrences(
now, repeatTimeZone, eventStart, eventEnd, RepeatPeriod.DAILY,
1, EndType.UNTIL, repeatEnd.time, AlarmInterval(AlarmIntervalUnit.DAY, 1), timeZone, emptyList()
now,
repeatTimeZone,
eventStart,
eventEnd,
RepeatPeriod.DAILY,
1,
EndType.UNTIL,
repeatEnd.time,
AlarmInterval(AlarmIntervalUnit.DAY, 1),
timeZone,
emptyList(),
emptyList()
) { time: Date, _: Int, _: Date? -> occurrences.add(time) }
val expected = listOf( // Event on 2nd, alarm on 1st
getDate(timeZone, 2019, 4, 1, 0, 0), // Event on 3rd, alarm on 2d
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,18 @@ import de.tutao.tutashared.push.SseStorage
import de.tutao.tutashared.toBase64
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito
import org.mockito.invocation.InvocationOnMock
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.stubbing.Answer
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.ConscryptMode
import java.security.KeyStoreException
import java.security.UnrecoverableEntryException
import java.util.Calendar
import java.util.Date
import java.util.concurrent.TimeUnit

@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE)
@ConscryptMode(ConscryptMode.Mode.OFF)
class AlarmNotificationsManagerTest {

private lateinit var manager: AlarmNotificationsManager
Expand Down
7 changes: 6 additions & 1 deletion app-android/tutashared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ android {
sourceSets {
this.getByName("debug").assets.srcDirs(files("$projectDir/schemas"))
}

ndkVersion = "26.1.10909125"
}

Expand Down Expand Up @@ -122,11 +123,15 @@ dependencies {
// JVM-based unit tests (that don't need a real device or emulator)
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version")

androidTestImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito-inline-extended:2.28.1") {
exclude(group = "org.mockito", module = "mockito-core")
}
androidTestImplementation("org.mockito:mockito-core:5.15.2")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.test:runner:1.6.1")
androidTestImplementation("androidx.test.ext:junit-ktx:1.2.1")
androidTestImplementation("androidx.test:rules:1.6.1")
androidTestImplementation("org.mockito:mockito-android:5.12.0")
androidTestImplementation("com.fasterxml.jackson.core:jackson-databind:2.17.2")
androidTestImplementation("androidx.room:room-testing:2.6.1")
}
Loading

0 comments on commit cf65d58

Please sign in to comment.