Mockito je framework s otevřeným zdrojovým kódem pro vytváření mock-objektů v jednotkových testech Java a Kotlin, který umožňuje izolovat testovaný kód od externích závislostí. S jeho pomocí vývojář nahrazuje skutečná úložiště, API klienty a databáze řízenými atrapami s daným chováním. Podle údajů Mockito.org je knihovna používána ve více než 60% Java projektů, které aplikují jednotkové testování.
Hlavní body
Mockito je knihovna s otevřeným zdrojovým kódem pro vytváření mock-objektů (atrap) v jednotkových testech v Javě, Kotlinu a dalších JVM jazycích. Na rozdíl od JUnit, který je zodpovědný za spouštění testů, Mockito řeší problém izolace — nahrazuje skutečné závislosti testované třídy předvídatelnými objekty.
Bez mocků vyžaduje testování metody, která přistupuje k databázi nebo externímu API, nastavení skutečného prostředí — nasazení DB, spuštění serveru. Mockito nahrazuje tyto závislosti objekty s pevným chováním: metoda repository.findById(1) vždy vrací určitý objekt User, aniž by přistupovala k databázi.
Architektura Mockito je založena na vzoru Proxy (pro rozhraní a třídy). Knihovna generuje podtřídu nebo proxy pro zadaný typ a zachycuje všechna volání metod, vracející výchozí hodnoty nebo hodnoty nastavené pomocí when().thenReturn().
Princip fungování Mockito je založen na třech základních operacích: vytvoření mocku, nastavení chování (stubbing) a ověření volání (verification). Každá operace používá statické metody z třídy org.mockito.Mockito — nejvíce načítané třídy v ekosystému Java podle statistik Maven Central. Všechna volání metod mocku jsou zaznamenávána v paměti, což umožňuje pozdější kontrolu pomocí verify.
Typický test s Mockito se skládá ze tří fází: Arrange — vytvoření mocků a nastavení stubů pomocí when().thenReturn(), Act — volání testované metody, Assert — kontrola výsledku pomocí assertEquals a verify(mock). Tento přístup se nazývá AAA (Arrange-Act-Assert).
Podívejme se na jednoduchý test, kde Mockito nahrazuje úložiště uživatelů. Metoda when().thenReturn() nastavuje mock tak, aby volání findById vracelo předem připravený objekt User.
// Vytváříme mock úložiště
UserRepository mockRepo = mock(UserRepository.class);
// Nastavujeme chování: při findById(1) vrať uživatele
when(mockRepo.findById(1)).thenReturn(new User("Alice"));
// Kontrolujeme, že metoda byla skutečně volána
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);
Mockito poskytuje dva způsoby vytváření mocků: statickou metodu mock(Class) a anotaci @Mock s inicializací pomocí MockitoAnnotations.openMocks(). První způsob je kompaktní pro jeden-dva mocky, druhý je pohodlný, když je závislostí mnoho — anotace snižují boilerplate kód.
Metoda mock() přijímá třídu a vrací objekt-atrapu, který lze nastavit pomocí when().thenReturn(). Všechny nenastavené metody vracejí výchozí hodnoty: 0 pro čísla, false pro boolean, null pro objekty.
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);
Anotace @Mock v kombinaci s @ExtendWith(MockitoExtension.class) automaticky vytváří mocky pro všechna pole testovací třídy. Rozšíření MockitoExtension je zodpovědné za inicializaci před každým testem.
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void getUserShouldReturnUserFromRepo() {
when(userRepository.findById(1)).thenReturn(new User("Alice"));
User result = userService.getUser(1);
assertEquals("Alice", result.getName());
}
}
Stubbing — proces určení toho, co má metoda mocku vrátit při volání s určitými argumenty. Základní syntaxe: when(mock.method(args)).thenReturn(value). Pro různé scénáře Mockito nabízí několik variant then-metod.
| Metoda | Účel |
|---|---|
| thenReturn(value) | Vždy vrací zadanou hodnotu |
| thenThrow(exception) | Při volání vyhazuje výjimku |
| thenAnswer(answer) | Dynamicky vypočítává návratovou hodnotu |
| thenCallRealMethod() | Volá skutečnou metodu (částečný mock) |
Když návratová hodnota závisí na argumentech volání, používá se thenAnswer s lambdou. To je užitečné pro simulaci práce s reálnými daty — například generování ID na základě předaného objektu.
when(repository.save(any())).thenAnswer(invocation -> {
User user = invocation.getArgument(0);
user.setId(42);
return user;
});
Verify je jedinečná schopnost Mockito, kterou starší knihovny mock-objektů (EasyMock, jMock) neposkytují.
Verify dělá testy spolehlivějšími, protože kontroluje nejen návratovou hodnotu, ale také vedlejší efekty — volání metod, které nevracejí výsledek (void metody). Metoda verify(mock).methodName(args) ověřuje, zda byla určitá metoda mocku volána se zadanými argumenty. To umožňuje testovat nejen výsledek, ale také proces — fakt obrácení se na závislost.
Ve výchozím nastavení verify kontroluje, že metoda byla volána právě jednou. Pokud je potřeba jiný počet — používají se times(n), atLeast(n), never() a další modifikátory z třídy Mockito.
// Kontrola počtu volání
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);
// Kontrola pořadí volání
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();
Když je třeba ověřit, s jakým přesným objektem byla metoda volána, používá se ArgumentCaptor. Ten zachycuje hodnotu argumentu během volání a umožňuje kontrolovat jeho pole samostatně. ArgumentCaptor je zvláště užitečný, když testovaný kód vytváří objekt uvnitř sebe a předává jej závislosti — tento objekt nelze jinak zkontrolovat.
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());
@Mock a @InjectMocks — dvě klíčové anotace Mockito, které výrazně snižují boilerplate kód. @Mock vytváří mock pro pole a @InjectMocks vkládá všechny mocky z testovací třídy do testovaného objektu pomocí konstruktoru, setteru nebo pole.
Mechanismus @InjectMocks se pokouší vložit závislosti v následujícím pořadí: konstruktor s největším počtem argumentů, setter podle typu, soukromé pole. Pokud žádný způsob nefunguje — objekt zůstává s null závislostmi a test selže s NullPointerException.
Je důležité pochopit: @InjectMocks neanalyzuje typy polí — vkládá jakýkoli mock kompatibilní podle typu. Pokud třída obsahuje dvě pole stejného typu — Mockito může vložit nesprávný mock. V takových případech se doporučuje použít explicitní konstruktor s předáním mocků.
V Android vývoji se Mockito používá společně s JUnit pro testování ViewModel, Repository a UseCase. Protože tyto třídy běží na JVM bez Android kontextu, Mockito nahrazuje jejich závislosti — Room DAO, Retrofit API, SharedPreferences — stuby s předvídatelným chováním.
Pro přidání Mockito do Android projektu stačí přidat závislost mockito-core nebo mockito-inline (ta podporuje mockování finálních tříd a statických metod). Verze 5.12.0 (2024) zahrnuje podporu Java 21 a vylepšenou integraci s JUnit 5.
// build.gradle.kts (modul)
dependencies {
testImplementation("org.mockito:mockito-core:5.12.0")
testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}
Dříve bylo pro mockování statických metod a konstruktorů vyžadováno PowerMock — rozšíření pracující pomocí bytecode instrumentace. Od Mockito 5.x s mockito-inline je tato funkce vestavěna přímo: mockStatic(ClassName.class) umožňuje mockovat statické metody bez dalších knihoven.
Typický scénář: ViewModel volá metodu úložiště a transformuje výsledek do UI stavu. Mockito nahrazuje úložiště a test kontroluje, že ViewModel správně zpracovává úspěšnou odpověď a chybu. Při použití Clean Architecture se vytvářejí mocky pro každou vrstvu: DataSource, Repository a UseCase — to umožňuje testovat každou vrstvu izolovaně.
Často kladené otázky
Mockito je knihovna pro Java a Kotlin používající proxy a reflexi. MockK je Kotlin-first knihovna s podporou korutin, extension funkcí a finálních tříd bez další konfigurace.
Od Mockito 2.1 je mockování finálních tříd podporováno pomocí opt-in. Ve verzi 5.x (mockito-inline) je to ve výchozím nastavení zapnuto. Stačí přidat závislost mockito-inline a použít standardní metodu mock().
Spy je částečný mock, který ve výchozím nastavení volá skutečné metody, ale umožňuje některé z nich přepsat pomocí when().thenReturn(). Spy je užitečný pro testování legacy kódu, když nelze přepsat celou třídu.
thenReturn vždy vrací stejnou hodnotu, bez ohledu na argumenty. thenAnswer vypočítává návratovou hodnotu na základě volání — argumentů, samotného mocku, stavu. Pro dynamické odpovědi vždy používejte thenAnswer.
Verify kontroluje nejen výsledek, ale také proces — fakt obrácení se na závislost. To je kritické pro služby, které musí ukládat data nebo odesílat oznámení. Bez verify test neodhalí, že metoda nevolala save() nebo send().
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také