0Pricing
Android Academy · Lektion

Unit-Tests mit JUnit

Schreiben Sie schnelle, zuverlässige Unit-Tests mit JUnit 4. Verwenden Sie @Test, @Before, @After und Assertions, testen Sie LiveData mit InstantTaskExecutorRule und Coroutines mit runTest.

Unit-Tests mit JUnit ist eine kostenlose Android Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Android Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum Tests schreiben?

Tests sind kein Luxus — sie sind Ihr Sicherheitsnetz:

  • Fehler erkennen, bevor es die Benutzer tun
  • Mit Zuversicht refaktorieren (wenn die Tests erfolgreich sind, ist nichts kaputtgegangen)
  • Das vorgesehene Verhalten dokumentieren
  • Regressionen beim Hinzufügen neuer Funktionen verhindern

Gut getesteter Code ist außerdem oft besser entworfen. Wenn er schwer zu testen ist, sind die Komponenten wahrscheinlich zu eng gekoppelt.

Arten von Android-Tests

Zwei Kategorien:

  • Unit-Tests (Ordner test/) — laufen auf der JVM, kein Gerät erforderlich. Schnell. Testen reine Kotlin-/Java-Logik.
  • Instrumentierte Tests (Ordner androidTest/) — laufen auf einem Gerät oder Emulator. Langsamer. Testen Android-spezifischen Code (Room-Datenbank, UI).

Bevorzugen Sie Unit-Tests für die Geschäftslogik. Verwenden Sie instrumentierte Tests nur, wenn Sie mit Android-APIs interagieren müssen.

JUnit-4-Einrichtung

JUnit 4 ist standardmäßig in Android-Projekten enthalten. Fügen Sie Folgendes zu app/build.gradle hinzu:

// app/build.gradle:
dependencies {
    testImplementation 'junit:junit:4.13.2'
    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
    testImplementation 'androidx.arch.core:core-testing:2.2.0'  // for LiveData
}

Ihr erster JUnit-Test

Erstellen Sie eine Klasse in src/test/java/ und annotieren Sie Testmethoden mit @Test:

import org.junit.Test
import org.junit.Assert.*

class CalculatorTest {

    private val calc = Calculator()

    @Test
    fun `addition returns correct sum`() {
        val result = calc.add(2, 3)
        assertEquals(5, result)
    }

    @Test
    fun `division by zero throws exception`() {
        assertThrows(ArithmeticException::class.java) {
            calc.divide(10, 0)
        }
    }
}

@Before und @After

Verwenden Sie Lifecycle-Annotationen, um den Zustand vor und nach jedem Test einzurichten beziehungsweise aufzuräumen:

class UserRepositoryTest {

    private lateinit var repo: UserRepository
    private lateinit var fakeDao: FakeUserDao

    @Before
    fun setUp() {
        fakeDao = FakeUserDao()          // fresh instance before each test
        repo = UserRepository(fakeDao)
    }

    @After
    fun tearDown() {
        fakeDao.clear()                  // clean up after each test
    }

    @Test
    fun `getUsers returns all users`() {
        fakeDao.insert(User(1, "Alice"))
        fakeDao.insert(User(2, "Bob"))
        assertEquals(2, repo.getUsers().size)
    }
}

Häufige Assertions

JUnit stellt Assertion-Methoden in Assert.* bereit:

// Equality:
assertEquals(expected, actual)
assertNotEquals(unexpected, actual)

// Null:
assertNull(value)
assertNotNull(value)

// Boolean:
assertTrue(condition)
assertFalse(condition)

// Same object reference:
assertSame(expected, actual)

// Custom message on failure:
assertEquals("User ID should be 1", 1, user.id)

// Exception:
assertThrows(IllegalArgumentException::class.java) {
    User(id = -1, name = "")
}

Ein ViewModel testen

Um LiveData zu testen, fügen Sie die InstantTaskExecutorRule hinzu, damit LiveData synchron postet:

class UserViewModelTest {

    @get:Rule
    val instantTaskRule = InstantTaskExecutorRule()

    private val fakeRepo = FakeUserRepository()
    private lateinit var viewModel: UserViewModel

    @Before
    fun setUp() {
        viewModel = UserViewModel(fakeRepo)
    }

    @Test
    fun `users are loaded on init`() {
        fakeRepo.usersToReturn = listOf(User(1, "Alice"), User(2, "Bob"))
        viewModel.loadUsers()

        val result = viewModel.users.value
        assertNotNull(result)
        assertEquals(2, result?.size)
    }
}

Coroutines testen

Verwenden Sie TestCoroutineDispatcher / StandardTestDispatcher, um die Ausführung von Coroutines in Tests zu steuern:

class SyncWorkerTest {

    @get:Rule
    val instantTaskRule = InstantTaskExecutorRule()

    private val testDispatcher = StandardTestDispatcher()

    @Before
    fun setUp() {
        Dispatchers.setMain(testDispatcher)
    }

    @After
    fun tearDown() {
        Dispatchers.resetMain()
    }

    @Test
    fun `sync completes successfully`() = runTest {
        val repo = FakeRepository()
        val worker = SyncUseCase(repo, testDispatcher)
        val result = worker.run()
        assertTrue(result.isSuccess)
    }
}

Fake oder Mock

Zwei Strategien, um echte Abhängigkeiten in Tests zu ersetzen:

  • Fake — eine funktionsfähige, für Tests entwickelte Implementierung (z. B. eine Liste im Speicher anstelle einer echten Datenbank). Einfach zu schreiben, gut lesbar, keine Bibliothek erforderlich.
  • Mock — ein automatisch generierter Stub, der Aufrufe aufzeichnet und Ihnen die Überprüfung von Interaktionen ermöglicht (Mockito, MockK). Leistungsfähiger, kann bei übermäßiger Verwendung jedoch instabil werden.

Bevorzugen Sie Fakes für einfache Fälle. Verwenden Sie Mocks, wenn Sie Methodenaufrufe überprüfen müssen.

Einen Fake schreiben

Ein Fake implementiert dieselbe Schnittstelle wie die echte Klasse, verwendet aber Speicher als Ablage:

interface UserDao {
    fun getAll(): List<User>
    fun insert(user: User)
}

class FakeUserDao : UserDao {
    private val storage = mutableListOf<User>()

    override fun getAll(): List<User> = storage.toList()
    override fun insert(user: User) { storage.add(user) }

    fun clear() { storage.clear() }
}

Konvention für Testnamen

Gute Testnamen beschreiben, was getestet wird, und nennen das erwartete Ergebnis. Verwenden Sie in Kotlin Funktionsnamen in Backticks, um gut lesbare Beschreibungen zu erhalten:

  • `getUsers returns empty list when no users exist`
  • `login throws exception when password is blank`
  • `add returns correct sum for negative numbers`

Muster: `subject does X when Y`

Kurze Überprüfung

Welchen Zweck erfüllt @Before in einer JUnit-Testklasse?

Zusammenfassung: Unit-Tests mit JUnit

Zuverlässige Apps sind getestete Apps:

  • Unit-Tests gehören in src/test/ und laufen auf der JVM — schnell
  • Mit @Test annotieren und assertEquals, assertTrue sowie assertThrows verwenden
  • @Before / @After für Einrichtung und Aufräumen
  • InstantTaskExecutorRule zum synchronen Testen von LiveData
  • runTest + StandardTestDispatcher zum Testen von Coroutines
  • Für einfache Ersetzungen Fakes gegenüber Mocks bevorzugen

Als Nächstes: Mocking mit Mockito zur Überprüfung von Interaktionen.

Häufig gestellte Fragen

Ist die Lektion „Unit-Tests mit JUnit“ kostenlos?

Ja — der vollständige Text von „Unit-Tests mit JUnit“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Android Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Unit-Tests mit JUnit“?

Schreiben Sie schnelle, zuverlässige Unit-Tests mit JUnit 4. Verwenden Sie @Test, @Before, @After und Assertions, testen Sie LiveData mit InstantTaskExecutorRule und Coroutines mit runTest. Du übst Android Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Android Academy zu starten?

Keine Vorkenntnisse erforderlich. Android Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.

Wie lange dauert die Lektion „Unit-Tests mit JUnit“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Android Academy-Lektion Code schreiben und ausführen?

Ja. Jede Android Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Unit-Tests mit JUnit
  2. Mocking mit Mockito
  3. UI-Tests mit Espresso
  4. Debugging und Profiling
← Zurück zu Android Academy