Ang Mockito ay isang open-source framework para sa paggawa ng mga mock-object sa mga unit test ng Java at Kotlin, na nagbibigay-daan sa paghihiwalay ng code na sinusubok mula sa mga panlabas na dependensiya. Sa tulong nito, pinapalitan ng developer ang mga tunay na repository, API client at database ng mga kontroladong peke na may itinakdang pag-uugali. Ayon sa datos ng Mockito.org, ang library ay ginagamit sa mahigit 60% ng mga proyektong Java na nag-aapply ng unit testing.
Mga Pangunahing Punto
Mockito ay isang open-source library para sa paggawa ng mga mock-object (pekeng bagay) sa mga unit test sa Java, Kotlin at iba pang mga wikang JVM. Hindi tulad ng JUnit na responsable sa pagpapatakbo ng mga test, nilulutas ng Mockito ang problema ng paghihiwalay — pinapalitan nito ang tunay na dependensiya ng klase na sinususubok ng mga bagay na mahuhulaan.
Kung walang mock, ang pag-test ng metodo na uma-access sa database o panlabas na API ay nangangailangan ng pag-set up ng tunay na kapaligiran — pag-deploy ng DB, pagsisimula ng server. Pinapalitan ng Mockito ang mga dependensiyang ito ng mga bagay na may nakapirming pag-uugali: ang metodo repository.findById(1) ay laging nagbabalik ng isang tiyak na User object, nang hindi uma-access sa database.
Ang arkitektura ng Mockito ay nakabatay sa pattern na Proxy (para sa mga interface at klase). Ang library ay bumubuo ng subclass o proxy para sa tinukoy na uri at humaharang sa lahat ng tawag sa metodo, na nagbabalik ng mga default na halaga o halagang itinakda sa pamamagitan ng when().thenReturn().
Ang prinsipyo ng paggana ng Mockito ay nakabatay sa tatlong pangunahing operasyon: paggawa ng mock, pagsasaayos ng pag-uugali (stubbing) at pag-verify ng mga tawag (verification). Bawat operasyon ay gumagamit ng mga static na metodo mula sa klase na org.mockito.Mockito — ang pinaka-load na klase sa Java ecosystem ayon sa estadistika ng Maven Central. Lahat ng tawag sa metodo ng mock ay naitatala sa memorya, na nagbibigay-daan sa pagsusuri sa pamamagitan ng verify.
Ang tipikal na test na may Mockito ay binubuo ng tatlong yugto: Arrange — paggawa ng mga mock at pagsasaayos ng mga stub sa pamamagitan ng when().thenReturn(), Act — pagtawag sa metodo na sinusubok, Assert — pagsusuri ng resulta sa pamamagitan ng assertEquals at verify(mock). Ang pamamaraang ito ay tinatawag na AAA (Arrange-Act-Assert).
Tingnan natin ang isang simpleng test kung saan pinapalitan ng Mockito ang repository ng mga gumagamit. Ang metodo na when().thenReturn() ay nagsasaayos ng mock upang ang tawag na findById ay magbalik ng isang inihandang User object.
// Gumagawa tayo ng mock ng repository
UserRepository mockRepo = mock(UserRepository.class);
// Inaayos ang pag-uugali: sa findById(1) ibalik ang gumagamit
when(mockRepo.findById(1)).thenReturn(new User("Alice"));
// Sinusuri kung ang metodo ay talagang tinawag
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);
Mockito ay nagbibigay ng dalawang paraan ng paggawa ng mock: ang static na metodo na mock(Class) at ang anotasyong @Mock na may inisyalisasyon sa pamamagitan ng MockitoAnnotations.openMocks(). Ang unang paraan ay kompact para sa isa-dalawang mock, ang pangalawa ay maginhawa kapag marami ang dependensiya — binabawasan ng mga anotasyon ang boilerplate code.
Ang metodo na mock() ay tumatanggap ng klase at nagbabalik ng pekeng bagay na maaaring i-configure sa pamamagitan ng when().thenReturn(). Lahat ng hindi naka-configure na metodo ay nagbabalik ng mga default na halaga: 0 para sa mga numero, false para sa boolean, null para sa mga bagay.
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);
Ang anotasyong @Mock kasama ng @ExtendWith(MockitoExtension.class) ay awtomatikong gumagawa ng mga mock para sa lahat ng field ng klase ng test. Ang extension na MockitoExtension ay responsable sa inisyalisasyon bago ang bawat test.
@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 — ang proseso ng pagtukoy kung ano ang dapat ibalik ng metodo ng mock kapag tinawag na may tiyak na mga argumento. Pangunahing syntax: when(mock.method(args)).thenReturn(value). Para sa iba't ibang senaryo, nag-aalok ang Mockito ng ilang variant ng then-metodo.
| Metodo | Layunin |
|---|---|
| thenReturn(value) | Laging nagbabalik ng tinukoy na halaga |
| thenThrow(exception) | Nagtatapon ng exception kapag tinawag |
| thenAnswer(answer) | Kinakalkula ang ibabalik na halaga nang dinamiko |
| thenCallRealMethod() | Tumatawag sa tunay na metodo (partial mock) |
Kapag ang ibabalik na halaga ay nakadepende sa mga argumento ng tawag, ginagamit ang thenAnswer na may lambda. Ito ay kapaki-pakinabang para sa paggaya ng trabaho sa tunay na datos — halimbawa, pagbuo ng ID batay sa inihang bagay.
when(repository.save(any())).thenAnswer(invocation -> {
User user = invocation.getArgument(0);
user.setId(42);
return user;
});
Verify ay isang natatanging kakayahan ng Mockito na hindi ibinibigay ng mas lumang mga library ng mock-object (EasyMock, jMock).
Ginagawa ng Verify na mas maaasahan ang mga test, dahil sinusuri nito hindi lamang ang ibinalik na halaga, kundi pati ang mga side effect — mga tawag sa metodo na hindi nagbabalik ng resulta (void na metodo). Ang metodo na verify(mock).methodName(args) ay sumusuri kung ang isang tiyak na metodo ng mock ay tinawag gamit ang tinukoy na mga argumento. Ito ay nagbibigay-daan sa pag-test hindi lamang ng resulta, kundi pati ng proseso — ang katotohanan ng pag-access sa dependensiya.
Bilang default, ang verify ay sumusuri na ang metodo ay tinawag nang eksaktong isang beses. Kung kailangan ng ibang bilang — ginagamit ang times(n), atLeast(n), never() at iba pang modifier mula sa klase na Mockito.
// Pagsusuri ng bilang ng mga tawag
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);
// Pagsusuri ng pagkakasunod-sunod ng mga tawag
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();
Kapag kailangan suriin kung anong eksaktong bagay ang ginamit sa pagtawag ng metodo, ginagamit ang ArgumentCaptor. Kinukuha nito ang halaga ng argumento sa oras ng tawag at nagbibigay-daan sa pagsusuri ng mga field nito nang magkakahiwalay. Ang ArgumentCaptor ay lalong kapaki-pakinabang kapag ang code na sinusubok ay gumagawa ng bagay sa loob at ipinapasa ito sa dependensiya — hindi mo masusuri ang bagay na ito sa ibang paraan.
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());
@Mock at @InjectMocks — dalawang pangunahing anotasyon ng Mockito na makabuluhang nagbabawas ng boilerplate code. Ang @Mock ay gumagawa ng mock para sa isang field, at ang @InjectMocks ay nag-i-inject ng lahat ng mock mula sa klase ng test patungo sa bagay na sinusubok sa pamamagitan ng constructor, setter o field.
Ang mekanismo ng @InjectMocks ay sumusubok na mag-inject ng mga dependensiya sa sumusunod na pagkakasunod-sunod: constructor na may pinakamaraming argumento, setter ayon sa uri, pribadong field. Kung walang paraan na gumana — ang bagay ay nananatili na may null na dependensiya at ang test ay nabigo sa NullPointerException.
Mahalagang maunawaan: @InjectMocks ay hindi sumusuri ng mga uri ng field — inilalagay nito ang anumang mock na tugma sa uri. Kung ang klase ay may dalawang field ng parehong uri — maaaring mag-inject ang Mockito ng maling mock. Sa ganitong mga kaso, inirerekomenda ang paggamit ng eksplisitong constructor na may pagpasa ng mga mock.
Sa pag-develop ng Android, ang Mockito ay ginagamit kasama ng JUnit para sa pag-test ng ViewModel, Repository at UseCase. Dahil ang mga klaseng ito ay tumatakbo sa JVM nang walang konteksto ng Android, pinapalitan ng Mockito ang kanilang mga dependensiya — Room DAO, Retrofit API, SharedPreferences — ng mga stub na may mahuhulaang pag-uugali.
Para idagdag ang Mockito sa proyektong Android, sapat na ang magdagdag ng dependensiya na mockito-core o mockito-inline (ang huli ay sumusuporta sa mocking ng mga final na klase at static na metodo). Ang bersyong 5.12.0 (2024) ay may kasamang suporta para sa Java 21 at pinahusay na integrasyon sa JUnit 5.
// build.gradle.kts (modul)
dependencies {
testImplementation("org.mockito:mockito-core:5.12.0")
testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}
Dati, para sa mocking ng mga static na metodo at constructor, kinakailangan ang PowerMock — isang extension na gumagana sa pamamagitan ng bytecode instrumentation. Simula sa Mockito 5.x na may mockito-inline, ang functionality na ito ay direktang naka-embed: ang mockStatic(ClassName.class) ay nagbibigay-daan sa mocking ng mga static na metodo nang walang karagdagang library.
Karaniwang senaryo: ViewModel ay tumatawag ng metodo ng repository at binabago ang resulta sa estado ng UI. Pinapalitan ng Mockito ang repository, at sinusuri ng test kung wastong pinoproseso ng ViewModel ang matagumpay na tugon at error. Sa arkitekturang Clean Architecture, ang mga mock ay ginagawa para sa bawat layer: DataSource, Repository at UseCase — ito ay nagbibigay-daan sa pag-test ng bawat layer nang hiwalay.
Mga Madalas Itanong
Mockito ay library para sa Java at Kotlin na gumagamit ng proxy at reflection. Ang MockK ay isang Kotlin-first library na may suporta para sa coroutine, extension function at final na klase nang walang karagdagang konfigurasyon.
Simula sa Mockito 2.1, ang mocking ng final na klase ay sinusuportahan sa pamamagitan ng opt-in. Sa bersyong 5.x (mockito-inline) ito ay naka-enable bilang default. Sapat na magdagdag ng dependensiya na mockito-inline at gamitin ang standard na mock() metodo.
Spy ay isang partial mock na bilang default ay tumatawag ng tunay na metodo, ngunit nagbibigay-daan na baguhin ang ilan sa mga ito sa pamamagitan ng when().thenReturn(). Ang Spy ay kapaki-pakinabang para sa pag-test ng legacy code kapag hindi maaaring isulat muli ang buong klase.
thenReturn ay laging nagbabalik ng parehong halaga, hindi alintana ang mga argumento. thenAnswer ay kinakalkula ang ibabalik na halaga batay sa tawag — mga argumento, ang mock mismo, estado. Para sa dinamikong sagot, laging gamitin ang thenAnswer.
Verify ay sumusuri hindi lamang ng resulta, kundi pati ng proseso — ang katotohanan ng pag-access sa dependensiya. Ito ay kritikal para sa mga serbisyo na dapat mag-save ng datos o magpadala ng notipikasyon. Kung walang verify, hindi matutuklasan ng test na ang metodo ay hindi tumawag ng save() o send().
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din