Jawaban singkatnya adalah bahwa dalam contoh Anda, hasil dari mock.method()akan berupa nilai kosong yang sesuai dengan tipe; mockito menggunakan tipuan melalui proksi, intersepsi metode, dan instance MockingProgresskelas yang dibagikan untuk menentukan apakah pemanggilan metode pada tiruan adalah untuk menghentikan atau memutar ulang perilaku stub yang ada daripada menyampaikan informasi tentang stubbing melalui nilai kembalian dari metode yang diejek.
Analisis mini dalam beberapa menit melihat kode mockito adalah sebagai berikut. Perhatikan, ini adalah deskripsi yang sangat kasar - ada banyak detail yang dimainkan di sini. Saya sarankan Anda memeriksa sendiri sumber di github .
Pertama, saat Anda memalsukan kelas menggunakan mockmetode Mockitokelas, pada dasarnya inilah yang terjadi:
Mockito.mockmendelegasikan ke org.mockito.internal.MockitoCore.mock, meneruskan pengaturan tiruan default sebagai parameter.
MockitoCore.mockdelegasi ke org.mockito.internal.util.MockUtil.createMock
- The
MockUtilkelas menggunakan ClassPathLoaderkelas untuk mendapatkan contoh MockMakergunakan untuk membuat tiruan tersebut. Secara default, kelas CgLibMockMaker digunakan.
CgLibMockMakermenggunakan kelas yang dipinjam dari JMock, ClassImposterizeryang menangani pembuatan tiruan. Potongan kunci dari 'sihir mockito' yang digunakan adalah yang MethodInterceptordigunakan untuk membuat tiruan: mockito MethodInterceptorFilter, dan rangkaian instance MockHandler, termasuk instance MockHandlerImpl . Interceptor metode meneruskan pemanggilan ke instance MockHandlerImpl, yang mengimplementasikan logika bisnis yang harus diterapkan ketika metode dipanggil pada tiruan (yaitu, mencari untuk melihat apakah jawaban sudah direkam, menentukan apakah pemanggilan tersebut merupakan rintisan baru, dll. Status defaultnya adalah jika stub belum terdaftar untuk metode yang dipanggil, nilai kosong yang sesuai dengan tipe akan dikembalikan.
Sekarang, mari kita lihat kode dalam contoh Anda:
when(mock.method()).thenReturn(someValue)
Berikut adalah urutan kode ini akan dijalankan:
mock.method()
when(<result of step 1>)
<result of step 2>.thenReturn
Kunci untuk memahami apa yang sedang terjadi adalah apa yang terjadi ketika metode pada tiruan dipanggil: metode interseptor memberikan informasi tentang pemanggilan metode, dan mendelegasikan ke rantai MockHandlerinstance-nya, yang akhirnya didelegasikan MockHandlerImpl#handle. Selama MockHandlerImpl#handle, penangan tiruan membuat instance dari OngoingStubbingImpldan meneruskannya ke MockingProgressinstance bersama .
Ketika whenmetode dipanggil setelah pemanggilan method(), itu mendelegasikan ke MockitoCore.when, yang memanggil stub()metode kelas yang sama. Metode ini membongkar stub yang sedang berlangsung dari MockingProgressinstance bersama yang menjadi tujuan method()penulisan pemanggilan palsu, dan mengembalikannya. Kemudian thenReturnmetode kemudian dipanggil pada OngoingStubbinginstance.