0Pricing
Android Academy · Lekcja

Mockowanie za pomocą Mockito

Izoluj zależności za pomocą Mockito i MockK. Konfiguruj wartości zwracane, weryfikuj interakcje, przechwytuj argumenty i używaj szpiegów do częściowego mockowania.

Mockowanie za pomocą Mockito to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 4 lekcji w sumie.

Czym jest mockowanie?

Mock to obiekt zastępczy, który w testach zastępuje prawdziwą zależność. W przeciwieństwie do obiektu Fake (działającej implementacji przechowywanej w pamięci), mock:

  • Jest automatycznie generowany przez bibliotekę
  • Rejestruje, które metody wywołano i z jakimi argumentami
  • Zwraca dowolną wartość, którą mu określisz (stubbing)
  • Pozwala weryfikować interakcje po zakończeniu testu

Konfiguracja Mockito

Dodaj Mockito i MockK (alternatywę skoncentrowaną na Kotlinie) do app/build.gradle:

// app/build.gradle:
testImplementation 'org.mockito:mockito-core:5.10.0'
testImplementation 'org.mockito.kotlin:mockito-kotlin:5.2.1'

// MockK (Kotlin-idiomatic alternative to Mockito):
testImplementation 'io.mockk:mockk:1.13.10'

Tworzenie mocków

Twórz mocki za pomocą mock() lub adnotacji @Mock:

import org.mockito.kotlin.*

interface UserApi {
    suspend fun fetchUsers(): List<User>
    suspend fun deleteUser(id: Int)
}

class RepositoryTest {

    // Option 1: create inline
    private val api: UserApi = mock()

    // Option 2: use annotation + MockitoJUnit4Runner
    @Mock lateinit var api2: UserApi

    @get:Rule
    val mockitoRule = MockitoJUnit.rule()
}

Stubbing — definiowanie zwracanych wartości

Użyj whenever(mock.method()).thenReturn(value), aby określić, co zwraca mock:

val api: UserApi = mock()

// Stub a return value:
whenever(api.fetchUsers()).thenReturn(
    listOf(User(1, "Alice"), User(2, "Bob"))
)

// Stub an exception:
whenever(api.fetchUsers()).thenThrow(RuntimeException("Network error"))

// Return different values on consecutive calls:
whenever(api.fetchUsers())
    .thenReturn(emptyList())           // first call
    .thenReturn(listOf(User(1, "Alice"))) // second call

verify() — sprawdzanie interakcji

Użyj verify(), aby sprawdzić, czy metoda została wywołana — i ile razy:

val api: UserApi = mock()
val repo = UserRepository(api)

repo.refreshUsers()

// Verify that fetchUsers() was called exactly once:
verify(api).fetchUsers()

// Verify called with specific argument:
repo.deleteUser(42)
verify(api).deleteUser(42)

// Verify called exactly 3 times:
verify(api, times(3)).fetchUsers()

// Verify never called:
verify(api, never()).deleteUser(any())

ArgumentCaptor

ArgumentCaptor przechwytuje argument przekazany do metody mocka, dzięki czemu można sprawdzić jego wartość:

val api: UserApi = mock()
val captor = argumentCaptor<User>()

val repo = UserRepository(api)
repo.saveUser(User(1, "Alice"))

verify(api).saveUser(captor.capture())

val captured = captor.firstValue
assertEquals(1, captured.id)
assertEquals("Alice", captured.name)

MockK — mockowanie skoncentrowane na Kotlinie

MockK został zaprojektowany z myślą o Kotlinie i natywnie obsługuje funkcje rozszerzające, korutyny oraz obiekty:

import io.mockk.*

val api = mockk<UserApi>()

// Stub:
every { api.fetchUsers() } returns listOf(User(1, "Alice"))

// Stub suspend function:
coEvery { api.fetchUsers() } returns listOf(User(1, "Alice"))

// Verify:
val repo = UserRepository(api)
runBlocking { repo.refresh() }
coVerify { api.fetchUsers() }

Mockowanie korutyn za pomocą MockK

Używaj coEvery i coVerify dla funkcji suspend:

val api = mockk<UserApi>()

// Stub suspend function:
coEvery { api.fetchUsers() } returns listOf(User(1, "Alice"))
coEvery { api.deleteUser(any()) } just Runs  // returns Unit

// Test:
runTest {
    val repo = UserRepository(api)
    repo.refresh()
    coVerify(exactly = 1) { api.fetchUsers() }
    coVerify(exactly = 0) { api.deleteUser(any()) }
}

Spy — częściowe mockowanie

spy opakowuje prawdziwy obiekt. Domyślnie wywoływane są prawdziwe metody, chyba że je nadpiszesz:

// Mockito Spy:
val realList = mutableListOf("a", "b", "c")
val spyList = spy(realList)

// Real method called:
spyList.add("d")
assertEquals(4, spyList.size)   // real add() was called

// Override specific method:
doReturn(99).`when`(spyList).size
assertEquals(99, spyList.size)  // overridden

// MockK Spy:
val spyObj = spyk(RealService())
every { spyObj.expensiveCall() } returns "fake result"

Kiedy używać mocków, a kiedy obiektów Fake

Praktyczne wskazówki:

  • Użyj obiektu Fake, gdy potrzebujesz działającej implementacji przechowywanej w pamięci (DAO, repozytorium) — jest łatwiejsza do odczytania i nie wymaga biblioteki
  • Użyj mocka, gdy musisz sprawdzić, czy konkretna metoda została wywołana z konkretnymi argumentami (zdarzenia analityczne, wywołania API)
  • Unikaj nadmiernego mockowania — jeśli zamockujesz wszystko, testy weryfikują mocki, a nie logikę

Typowe błędy

Pułapki, których należy unikać podczas mockowania:

  • Mockowanie obiektów wartości — mockuj interfejsy/abstrakcje, a nie klasy danych
  • Zbyt głębokie mockowanie — jeśli w jednym teście potrzebujesz 5 mocków, kod jest zbyt silnie powiązany
  • Brak weryfikacji, gdy interakcja ma znaczenie — nie ograniczaj się do definiowania zachowania, wykonuj również weryfikację
  • Mockito i wartości domyślne Kotlina — parametry Kotlina domyślnie nie mogą mieć wartości null; używaj mockito-kotlin lub MockK, aby uniknąć niespodziewanych wartości null

Mockowanie obiektów i obiektów towarzyszących

MockK może mockować obiekty Kotlina i obiekty towarzyszące — czego nie da się zrobić za pomocą Mockito:

object DateProvider {
    fun today(): String = "2024-01-01"
}

// In test:
mockkObject(DateProvider)
every { DateProvider.today() } returns "2099-12-31"

val result = DateProvider.today()
assertEquals("2099-12-31", result)

// Restore after test:
unmockkObject(DateProvider)

Szybki test

Jaki jest cel funkcji verify() w teście Mockito lub MockK?

Podsumowanie: mockowanie z Mockito i MockK

Mocki pozwalają izolować i weryfikować zachowanie:

  • mock() / mockk() — tworzenie mocka na podstawie interfejsu lub klasy
  • whenever(...).thenReturn(...) / every { } returns ... — definiowanie zwracanych wartości
  • coEvery / coVerify — dla funkcji suspend Kotlina (MockK)
  • verify(mock).method(args) — sprawdzanie, czy metoda została wywołana
  • ArgumentCaptor — przechwytywanie i sprawdzanie argumentów
  • spy() / spyk() — częściowe mockowanie prawdziwego obiektu
  • Preferuj obiekty Fake dla danych; używaj mocków do weryfikowania zachowania

Następnie: testowanie interfejsu użytkownika za pomocą Espresso.

Często zadawane pytania

Czy lekcja „Mockowanie za pomocą Mockito” jest bezpłatna?

Tak — pełny tekst „Mockowanie za pomocą Mockito” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Mockowanie za pomocą Mockito”?

Izoluj zależności za pomocą Mockito i MockK. Konfiguruj wartości zwracane, weryfikuj interakcje, przechwytuj argumenty i używaj szpiegów do częściowego mockowania. Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Android Academy?

Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Mockowanie za pomocą Mockito”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?

Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Testy jednostkowe z JUnit
  2. Mockowanie za pomocą Mockito
  3. Testowanie interfejsu z Espresso
  4. Debugowanie i profilowanie
← Powrót do Android Academy