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 callverify() — 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-kotlinlub 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 klasywhenever(...).thenReturn(...)/every { } returns ...— definiowanie zwracanych wartościcoEvery/coVerify— dla funkcji suspend Kotlina (MockK)verify(mock).method(args)— sprawdzanie, czy metoda została wywołanaArgumentCaptor— przechwytywanie i sprawdzanie argumentówspy()/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
- Testy jednostkowe z JUnit
- Mockowanie za pomocą Mockito
- Testowanie interfejsu z Espresso
- Debugowanie i profilowanie