Mockito — bu nədir, əsas anlayışlar və iş prinsipi

Müəllif: IT Sectr Dərc olunub: 2026-04-08 Oxuma vaxtı: 8 dəq

Mockito — Java və Kotlin-də modul testlərində mock-obyektlər yaratmaq üçün açıq mənbəli bir freymvorkdur. Bu, test edilən kodu xarici asılılıqlardan təcrid etməyə imkan verir. Onun köməyi ilə tərtibatçı real repozitoriləri, API müştərilərini və verilənlər bazalarını idarə olunan saxta obyektlərlə əvəz edir. Mockito.org məlumatlarına görə, kitabxana modul testləri tətbiq edən Java layihələrinin 60%-dən çoxunda istifadə olunur.

Əsas məqamlar

  • Mockito — testlərdə real asılılıqları əvəz edən mock-obyektlər yaratmaq üçün kitabxana.
  • Mock — real komponentin davranışını təqlid edən saxta obyekt.
  • Stubbing — mock metodunun çağırışında qaytarılan dəyərin konfiqurasiyası.
  • Verify — metodun müəyyən arqumentlərlə çağırıldığını yoxlamaq.
  • @InjectMocks — mock asılılıqlarının test edilən obyektə avtomatik yerləşdirilməsi.

Mockito nədir?

Mockito — Java, Kotlin və digər JVM dillərində modul testlərində mock-obyektlər (saxta obyektlər) yaratmaq üçün açıq mənbəli kitabxana. JUnit testlərin işə salınmasına cavabdeh olduğu halda, Mockito təcridetmə problemini həll edir — test edilən sinfin real asılılıqlarını proqnozlaşdırıla bilən obyektlərlə əvəz edir.

Mocklar olmadan verilənlər bazasına və ya xarici API-yə müraciət edən metodu test etmək real mühitin qurulmasını tələb edir — DB-nin yerləşdirilməsi, serverin işə salınması. Mockito bu asılılıqları sabit davranışlı obyektlərlə əvəz edir: repository.findById(1) metodu verilənlər bazasına müraciət etmədən həmişə müəyyən User obyektini qaytarır.

Mockito arxitekturası Proxy nümunəsinə əsaslanır (interfeyslər və siniflər üçün). Kitabxana müəyyən tip üçün alt sinif və ya proxy yaradır və bütün metod çağırışlarını ələ keçirərək standart və ya when().thenReturn() ilə təyin edilmiş dəyərləri qaytarır.

Mockito necə işləyir

İş prinsipi Mockito üç əsas əməliyyata əsaslanır: mock yaratma, davranışın konfiqurasiyası (stubbing) və çağırışların yoxlanması (verification). Hər bir əməliyyat Maven Central statistikasına görə Java ekosistemində ən çox yüklənən sinif olan org.mockito.Mockito sinfindən statik metodlardan istifadə edir. Mock-un bütün metod çağırışları yaddaşda qeydə alınır ki, bu da onları sonradan verify vasitəsilə yoxlamağa imkan verir.

Mockito ilə testin üç addımı

Mockito ilə tipik test üç fazadan ibarətdir: Arrange — mockların yaradılması və stub-ların when().thenReturn() ilə konfiqurasiyası, Act — test edilən metodun çağırılması, Assert — nəticənin assertEquals və verify(mock) ilə yoxlanması. Bu yanaşma AAA (Arrange-Act-Assert) adlanır.

Repozitoriya mock ilə əsas nümunə

Mockito-nun istifadəçi repozitorisini əvəz etdiyi sadə bir testə baxaq. when().thenReturn() metodu mock-u elə konfiqurasiya edir ki, findById çağırışı əvvəlcədən hazırlanmış User obyektini qaytarsın.

java
// Repozitoriya mock-u yaradırıq
UserRepository mockRepo = mock(UserRepository.class);

// Davranışı konfiqurasiya edirik: findById(1) çağırıldıqda istifadəçini qaytar
when(mockRepo.findById(1)).thenReturn(new User("Alice"));

// Metodun həqiqətən çağırıldığını yoxlayırıq
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);

Mock-obyektlərin yaradılması

Mockito mock yaratmağın iki yolunu təqdim edir: statik mock(Class) metodu və MockitoAnnotations.openMocks() ilə işə salınan @Mock annotasiyası. Birinci üsul bir-iki mock üçün yığcamdır, ikincisi isə çoxlu asılılıq olduqda rahatdır — annotasiyalar boilerplate kodu azaldır.

Statik mock() metodu ilə

mock() metodu sinfi qəbul edir və when().thenReturn() ilə konfiqurasiya edilə bilən saxta obyekt qaytarır. Konfiqurasiya edilməmiş metodlar standart dəyərlər qaytarır: ədədlər üçün 0, boolean üçün false, obyektlər üçün null.

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

@Mock annotasiyası ilə JUnit 5-də

@Mock annotasiyası @ExtendWith(MockitoExtension.class) ilə birlikdə test sinfinin bütün sahələri üçün avtomatik mocklar yaradır. MockitoExtension genişlənməsi hər testdən əvvəl işə salınmaya cavabdehdir.

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: mock davranışının konfiqurasiyası

Stubbing — müəyyən arqumentlərlə çağırıldıqda mock metodunun nə qaytarmalı olduğunu təyin etmə prosesi. Əsas sintaksis: when(mock.method(args)).thenReturn(value). Müxtəlif ssenarilər üçün Mockito bir neçə then-metodu variantı təklif edir.

MetodMəqsəd
thenReturn(value)Həmişə göstərilən dəyəri qaytarır
thenThrow(exception)Çağırış zamanı istisna atır
thenAnswer(answer)Qaytarılan dəyəri dinamik hesablayır
thenCallRealMethod()Həqiqi metodu çağırır (qismən mock)

thenAnswer ilə dinamik cavab

Qaytarılan dəyər çağırış arqumentlərindən asılı olduqda, lambda ilə thenAnswer istifadə olunur. Bu, real verilənlərlə işin təqlid edilməsi üçün faydalıdır — məsələn, ötürülən obyekt əsasında ID generasiyası.

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

Verify: mock ilə qarşılıqlı əlaqələrin yoxlanması

Verify — Mockito-nun unikal imkanıdır, onu köhnə mock-obyekt kitabxanaları (EasyMock, jMock) təmin etmir.

Verify testləri daha etibarlı edir, çünki yalnız qaytarılan dəyəri deyil, həm də yan təsirləri — nəticə qaytarmayan metod çağırışlarını (void metodları) yoxlayır. verify(mock).methodName(args) metodu müəyyən mock metodunun göstərilən arqumentlərlə çağırılıb-çağırılmadığını yoxlayır. Bu, təkcə nəticəni deyil, həm də prosesi — asılılığa müraciət faktını test etməyə imkan verir.

Çağırış sayının yoxlanması

Standart olaraq verify metodun dəqiq bir dəfə çağırıldığını yoxlayır. Fərqli say lazım olduqda — times(n), atLeast(n), never()Mockito sinfindən digər modifikatorlardan istifadə olunur.

java
// Çağırış sayının yoxlanması
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);

// Çağırış ardıcıllığının yoxlanması
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();

Arqumentlərin tutulması üçün ArgumentCaptor

Metodun hansı obyektlə çağırıldığını yoxlamaq lazım olduqda ArgumentCaptor istifadə olunur. O, çağırış zamanı arqumentin dəyərini tutur və onun sahələrini ayrıca yoxlamağa imkan verir. ArgumentCaptor xüsusilə test edilən kodun daxildə obyekt yaradıb onu asılılığa ötürdüyü hallarda faydalıdır — bu obyekti başqa cür yoxlamaq mümkün deyil.

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

@Mock və @InjectMocks annotasiyaları

@Mock@InjectMocks — Mockito-nun iki əsas annotasiyasıdır ki, onlar boilerplate kodu əhəmiyyətli dərəcədə azaldır. @Mock sahə üçün mock yaradır, @InjectMocks isə test sinfindən bütün mockları test edilən obyektə konstruktor, setter və ya sahə vasitəsilə yerləşdirir.

@InjectMocks mexanizmi asılılıqları aşağıdakı ardıcıllıqla yerləşdirməyə çalışır: ən çox arqumentə malik konstruktor, tipə görə setter, özəl sahə. Heç bir üsul işləməzsə — obyekt null asılılıqları ilə qalır və test NullPointerException ilə çökür.

@InjectMocks istifadə qaydaları

Anlamaq vacibdir: @InjectMocks sahələrin tiplərini təhlil etmir — tipə uyğun gələn istənilən mock-u yerləşdirir. Sinifdə eyni tipdə iki sahə varsa — Mockito səhv mock-u yerləşdirə bilər. Belə hallarda mockların ötürülməsi ilə açıq konstruktordan istifadə etmək tövsiyə olunur.

Android layihələrində Mockito

Android inkişafında Mockito JUnit ilə birlikdə ViewModel, Repository və UseCase-in test edilməsi üçün istifadə olunur. Bu siniflər Android konteksti olmadan JVM-də işlədiyi üçün Mockito onların asılılıqlarını — Room DAO, Retrofit API, SharedPreferences — proqnozlaşdırıla bilən davranışlı stub-larla əvəz edir.

Mockito üçün Gradle konfiqurasiyası

Mockito-nu Android layihəsinə əlavə etmək üçün mockito-core və ya mockito-inline asılılığını əlavə etmək kifayətdir (sonuncu final siniflərin və statik metodların mock edilməsini dəstəkləyir). 5.12.0 versiyası (2024) Java 21 dəstəyi və JUnit 5 ilə təkmilləşdirilmiş inteqrasiya daxildir.

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

Mockito və PowerMock: köhnəlmiş təcrübə

Əvvəllər statik metodların və konstruktorların mock edilməsi üçün baytkod instrumentasiyası ilə işləyən PowerMock genişlənməsi tələb olunurdu. Mockito 5.x-dən mockito-inline ilə bu funksionallıq birbaşa daxil edilmişdir: mockStatic(ClassName.class) əlavə kitabxanalar olmadan statik metodları mock etməyə imkan verir.

ViewModel-in Mockito ilə test edilməsi

Tipik ssenari: ViewModel repozitoriya metodunu çağırır və nəticəni UI vəziyyətinə çevirir. Mockito repozitoriyanı əvəz edir, test isə ViewModel-in uğurlu cavabı və xətanı düzgün emal etdiyini yoxlayır. Clean Architecture tətbiq edildikdə, hər təbəqə üçün mocklar yaradılır: DataSource, Repository və UseCase — bu, hər təbəqəni təcrid olunmuş şəkildə test etməyə imkan verir.

  • success case — when(repo.getData()).thenReturn(Result.success(data)) → state = Success(data) yoxlayırıq.
  • error case — when(repo.getData()).thenReturn(Result.error(exception)) → state = Error(message) yoxlayırıq.
  • loading state — verify, ViewModel-in repozitoriyanı çağırmazdan əvvəl isLoading = true təyin etdiyini yoxlayırıq.

Tez-tez verilən suallar

Mockito MockK-dan nə ilə fərqlənir?

Mockito — proxy və refleksiyadan istifadə edən Java və Kotlin üçün kitabxana. MockK — koroutine, genişləndirmə funksiyaları və final siniflərini əlavə konfiqurasiya olmadan dəstəkləyən Kotlin-first kitabxana.

Mockito-da final sinif üçün mock necə yaradılır?

Mockito 2.1-dən etibarən final siniflərin mock edilməsi opt-in vasitəsilə dəstəklənir. 5.x versiyasında (mockito-inline) bu standart olaraq aktivdir. Sadəcə mockito-inline asılılığını əlavə etmək və standart mock() metodundan istifadə etmək kifayətdir.

Mockito-da Spy nədir?

Spy — standart olaraq real metodları çağıran, lakin bəzilərini when().thenReturn() ilə əvəz etməyə imkan verən qismən mock-dur. Spy bütün sinfi yenidən yazmaq mümkün olmayan legacy-kodun test edilməsi üçün faydalıdır.

thenReturn ilə thenAnswer arasında nə fərq var?

thenReturn arqumentlərdən asılı olmayaraq həmişə eyni dəyəri qaytarır. thenAnswer qaytarılan dəyəri invocation əsasında hesablayır — çağırış arqumentləri, mock-un özü, vəziyyət. Dinamik cavablar üçün həmişə thenAnswer istifadə edin.

Niyə verify mock-larla testlərdə vacibdir?

Verify təkcə nəticəni deyil, həm də prosesi — asılılığa müraciət faktını yoxlayır. Bu, məlumatları saxlamalı və ya bildirişlər göndərməli olan xidmətlər üçün kritikdir. Verify olmadan test metodun save() və ya send() çağırmadığını aşkar etməyəcək.

Xülasə

  • Mockito — Java və Kotlin-də mock etmək üçün de facto standart olan mock-obyekt kitabxanası.
  • Mocklar mock(Class) və ya @Mock annotasiyası ilə MockitoExtension ilə yaradılır.
  • Stubbing when().thenReturn() vasitəsilə mock metodlarının davranışını təyin edir.
  • Verify mock metodlarının müəyyən arqumentlərlə çağırılma faktını və sayını yoxlayır.
  • @InjectMocks avtomatik olaraq mockları test edilən obyektə yerləşdirir.
  • Android inteqrasiyası — Mockito ViewModel, Repository və UseCase-in test edilməsi üçün istifadə olunur.
  • ArgumentCaptor obyektin sahələrinin ətraflı yoxlanması üçün çağırış arqumentlərini tutur.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun