Saya menggunakan Mockito 1.9.0. Saya ingin mengejek perilaku untuk metode tunggal kelas dalam tes JUnit, jadi saya punya
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
Masalahnya adalah, pada baris kedua, myClassSpy.method1()
sebenarnya dipanggil, menghasilkan pengecualian. Satu-satunya alasan saya menggunakan ejekan adalah agar nanti, kapan pun myClassSpy.method1()
dipanggil, metode sebenarnya tidak akan dipanggil dan myResults
objek akan dikembalikan.
MyClass
adalah antarmuka dan myInstance
merupakan implementasi dari itu, jika itu penting.
Apa yang harus saya lakukan untuk memperbaiki perilaku memata-matai ini?
Jawaban:
Izinkan saya mengutip dokumentasi resmi :
Dalam kasus Anda itu berlangsung seperti:
sumber
send
dipanggilKasus saya berbeda dari jawaban yang diterima. Saya mencoba untuk mengejek metode paket-pribadi untuk contoh yang tidak hidup dalam paket itu
dan kelas tes
Kompilasi itu benar, tetapi ketika mencoba untuk mengatur tes, itu memanggil metode yang sebenarnya.
Menyatakan metode yang dilindungi atau publik memperbaiki masalah, itu bukan solusi bersih.
sumber
Dalam kasus saya, menggunakan Mockito 2.0, saya harus mengubah semua
any()
parameternullable()
untuk mematikan panggilan sebenarnya.sumber
foo = Mockito.spy(foo);
Mockito.doReturn(someValue).when(foo).methodToPrevent(nullable(ArgumentType.class));
any
daneq
korek api.Jawaban oleh Tomasz Nurkiewicz tampaknya tidak menceritakan keseluruhan cerita!
NB Mockito versi: 1.10.19.
Saya seorang pemula Mockito, jadi tidak bisa menjelaskan perilaku berikut: jika ada seorang ahli di luar sana yang dapat meningkatkan jawaban ini, silakan saja.
Metode yang dimaksud di sini,
getContentStringValue
adalah TIDAKfinal
dan TIDAKstatic
.Baris ini memang memanggil metode asli
getContentStringValue
:Baris ini tidak memanggil metode asli
getContentStringValue
:Untuk alasan yang tidak dapat saya jawab, menggunakan
isA()
penyebab perilaku (?) "Jangan panggil metode"doReturn
gagal.Mari kita lihat tanda tangan metode yang terlibat di sini: keduanya adalah
static
metodeMatchers
. Keduanya dikatakan oleh Javadoc untuk kembalinull
, yang agak sulit untuk membuat kepala Anda berputar. AgaknyaClass
objek diteruskan sebagai parameter diperiksa tetapi hasilnya tidak pernah dihitung atau dibuang. Mengingat bahwanull
dapat berdiri untuk kelas apa pun dan bahwa Anda berharap metode yang diejek tidak dapat dipanggil, tidak dapat tanda tanganisA( ... )
danany( ... )
hanya kembalinull
daripada parameter generik *<T>
?Bagaimanapun:
Dokumentasi API tidak memberikan petunjuk tentang hal ini. Tampaknya juga mengatakan perlunya perilaku "jangan panggil metode" semacam itu "sangat jarang". Secara pribadi saya menggunakan teknik ini sepanjang waktu : biasanya saya menemukan bahwa mengejek melibatkan beberapa baris yang "mengatur adegan" ... diikuti dengan memanggil metode yang kemudian "memainkan" adegan dalam konteks tiruan yang telah Anda tampilkan .. ... dan saat Anda mengatur pemandangan dan alat peraga, hal terakhir yang Anda inginkan adalah para aktor memasuki panggung kiri dan mulai memerankan hati mereka ...
Tapi ini jauh melampaui nilai gajiku ... Aku mengundang penjelasan dari pendeta tinggi Mockito yang lewat ...
* Apakah "parameter umum" istilah yang tepat?
sumber
Satu lagi skenario yang mungkin menyebabkan masalah dengan mata-mata adalah ketika Anda menguji kacang musim semi (dengan kerangka uji pegas) atau kerangka kerja lain yang memeriksa objek Anda selama pengujian .
Contoh
Dalam kode di atas baik Spring dan Mockito akan mencoba untuk mem-proxy objek MonitoringDocumentsRepository Anda, tetapi Spring akan menjadi yang pertama, yang akan menyebabkan panggilan nyata metode findMonitoringDocuments. Jika kita men-debug kode kita setelah meletakkan mata-mata pada objek repositori, maka akan terlihat seperti ini di dalam debugger:
@SpyBean untuk menyelamatkan
Jika bukan
@Autowired
anotasi, kami menggunakan@SpyBean
anotasi, kami akan menyelesaikan masalah di atas, anotasi SpyBean juga akan menyuntikkan objek repositori tetapi akan terlebih dahulu diproksi oleh Mockito dan akan terlihat seperti ini di dalam debuggerdan ini kodenya:
sumber
Saya telah menemukan alasan lain bagi mata-mata untuk memanggil metode asli.
Seseorang memiliki ide untuk mengejek
final
kelas, dan menemukan tentangMockMaker
:Sumber: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
Setelah saya bergabung dan membawa file itu ke mesin saya, tes saya gagal.
Saya hanya harus menghapus baris (atau file), dan
spy()
berhasil.sumber
Agak terlambat ke pesta tetapi solusi di atas tidak bekerja untuk saya, jadi bagikan $ 0,02 saya
Versi Mokcito: 1.10.19
MyClass.java
Test.java
Berikut ini TIDAK bekerja untuk saya (metode aktual dipanggil):
1.
2.
3.
Berikut BEKERJA:
sumber
Salah satu cara untuk memastikan metode dari kelas tidak dipanggil adalah dengan mengganti metode dengan dummy.
sumber
Jawaban untuk pengguna scala: Menempatkan
doReturn
lebih dulu tidak berhasil! Lihat posting ini .sumber