Mockito — ano ito, mahahalagang konsepto at prinsipyo ng paggana

May-akda: IT Sectr Nai-publish: 2026-04-08 Oras ng pagbabasa: 8 min

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 — library para sa paggawa ng mga mock-object na pumapalit sa tunay na dependensiya sa mga test.
  • Mock — isang pekeng bagay na ginagaya ang pag-uugali ng tunay na komponente.
  • Stubbing — pagsasaayos ng halagang ibabalik kapag tinawag ang metodo ng mock.
  • Verify — pagsusuri kung ang metodo ay tinawag gamit ang tiyak na mga argumento.
  • @InjectMocks — awtomatikong pag-inject ng mga mock-dependensiya sa bagay na sinusubok.

Ano ang Mockito?

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().

Paano gumagana ang Mockito

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.

Tatlong hakbang ng test na may Mockito

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).

Pangunahing halimbawa na may mock ng repository

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.

java
// 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);

Paggawa ng mga mock-object

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.

Sa pamamagitan ng static na metodo na mock()

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.

java
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);

Sa pamamagitan ng anotasyong @Mock na may JUnit 5

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.

java
@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: pagsasaayos ng pag-uugali ng mock

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.

MetodoLayunin
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)

Dinamikong sagot sa pamamagitan ng thenAnswer

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.

java
when(repository.save(any())).thenAnswer(invocation -> {
    User user = invocation.getArgument(0);
    user.setId(42);
    return user;
});

Verify: pagsusuri ng mga interaksyon sa mock

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.

Pagsusuri ng bilang ng mga tawag

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.

java
// 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();

ArgumentCaptor para sa pagkuha ng mga argumento

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.

java
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());

Mga anotasyong @Mock at @InjectMocks

@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.

Mga patakaran sa paggamit ng @InjectMocks

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.

Mockito sa mga proyektong Android

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.

Konfigurasyon ng Gradle para sa Mockito

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.

kotlin
// build.gradle.kts (modul)
dependencies {
    testImplementation("org.mockito:mockito-core:5.12.0")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}

Mockito at PowerMock: lumang kasanayan

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.

Pagsubok ng ViewModel gamit ang Mockito

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.

  • success case — when(repo.getData()).thenReturn(Result.success(data)) → sinusuri natin ang state = Success(data).
  • error case — when(repo.getData()).thenReturn(Result.error(exception)) → sinusuri natin ang state = Error(message).
  • loading state — verify na ang ViewModel ay nagtakda ng isLoading = true bago tawagan ang repository.

Mga Madalas Itanong

Paano naiiba ang Mockito sa MockK?

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.

Paano gumawa ng mock para sa final na klase sa Mockito?

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.

Ano ang Spy sa Mockito?

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.

Ano ang pagkakaiba ng thenReturn at thenAnswer?

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.

Bakit mahalaga ang verify sa mga test na may mock?

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

  • Mockito — library para sa paggawa ng mga mock-object, de facto standard para sa mocking sa Java at Kotlin.
  • Mga Mock ay ginagawa sa pamamagitan ng mock(Class) o anotasyong @Mock na may MockitoExtension.
  • Stubbing sa pamamagitan ng when().thenReturn() ay nagtatakda ng pag-uugali ng mga metodo ng mock.
  • Verify ay sumusuri ng katotohanan at bilang ng mga tawag sa metodo ng mock na may tinukoy na argumento.
  • @InjectMocks ay awtomatikong nag-i-inject ng mga mock sa bagay na sinusubok.
  • Integrasyon sa Android — Ginagamit ang Mockito para sa pag-test ng ViewModel, Repository at UseCase.
  • ArgumentCaptor ay kumukuha ng mga argumento ng tawag para sa detalyadong pagsusuri ng mga field ng bagay.

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.

Pag-usapan ang proyekto

Basahin din