Ok, bagaimana dengan kerangka java mocking pada umumnya ... Apakah ini mungkin dengan kerangka kerja lain, atau haruskah saya membuat rintisan bodoh untuk meniru perilaku yang saya inginkan?
Abhijeet Kashnia
Jawaban:
1001
Anda dapat membuat Jawaban di Mockito. Mari kita asumsikan, kita memiliki antarmuka bernama Aplikasi dengan metode myFunction.
Ini juga yang saya cari. Terima kasih! Tapi masalah saya berbeda. Saya ingin mengejek layanan ketekunan (EJB) yang menyimpan objek dan mengembalikannya dengan nama.
migu
7
Saya membuat kelas tambahan yang membungkus penciptaan jawaban. Jadi kodenya berbunyi sepertiwhen(...).then(Return.firstParameter())
SpaceTrucker
69
Dengan Java 8 lambdas, sangat mudah untuk mengembalikan argumen pertama, bahkan untuk kelas tertentu, yaitu when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class)). Dan Anda bisa menggunakan referensi metode dan memanggil metode nyata.
Paweł Dyda
Ini memecahkan masalah saya dengan metode pengembalian Iterator<? extends ClassName>yang menyebabkan semua jenis masalah dalam thenReturn()pernyataan.
Michael Shopsin
16
Dengan Java 8 dan Mockito <1.9.5 maka jawaban Paweł menjadiwhen(foo(any()).thenAnswer(i -> i.getArguments()[0])
Graeme Moss
567
Jika Anda memiliki Mockito 1.9.5 atau lebih tinggi, ada metode statis baru yang dapat membuat Answerobjek untuk Anda. Anda perlu menulis sesuatu seperti
Perhatikan bahwa returnsFirstArg()metode ini statis di AdditionalAnswerskelas, yang baru untuk Mockito 1.9.5; jadi Anda akan memerlukan impor statis yang tepat.
Catatan: itu when(...).then(returnsFirstArg()), saya keliru when(...).thenReturn(returnsFirstArg())yang memberijava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
Benedikt Köppel
1
Catatan: returnsFirstArg () mengembalikan Jawaban <> daripada nilai argumen. Mendapat 'Foo (java.lang.String) tidak dapat diterapkan ke' (org.mockito.stubbing.Answer <java.lang.Object>) '' ketika mencoba menelepon .thenReturn (Foo baru (returnsFirstArg ()))
Lu55
Saya selalu perlu google jawaban ini lagi dan lagi dan lagi selama beberapa tahun terakhir, karena saya tidak dapat mengingat "AdditionalAnswers" dan saya hanya membutuhkannya sangat jarang. Lalu saya bertanya-tanya bagaimana sih saya bisa membangun skenario itu karena saya tidak dapat menemukan dependensi yang diperlukan. Tidak bisakah ini ditambahkan langsung ke mockito? : /
BAERUS
2
Jawaban Steve lebih umum. Yang ini hanya memungkinkan Anda untuk mengembalikan argumen mentah. Jika Anda ingin memproses argumen itu dan mengembalikan hasilnya, maka Steve menjawab aturan. Saya membatalkan keduanya karena keduanya berguna.
akostadinov
FYI, kita harus mengimpor static org.mockito.AdditionalAnswers.returnsFirstArg. ini untuk menggunakan returnsFirstArg. Juga, saya bisa melakukannya when(myMock.myFunction(any())).then(returnsFirstArg())di Mockito 2.20. *
gtiwari333
78
Dengan Java 8 dimungkinkan untuk membuat jawaban satu baris bahkan dengan versi Mockito yang lebih lama:
Tentu saja ini tidak berguna seperti yang AdditionalAnswersdisarankan oleh David Wallace, tetapi mungkin berguna jika Anda ingin mengubah argumen "dengan cepat".
Cemerlang. Terima kasih. Jika argumennya adalah long, apakah ini masih bisa bekerja dengan tinju dan Long.class?
vikingsteve
1
.getArgumentAt (..) tidak ditemukan untuk saya tetapi .getArgument (1) berhasil (mockito 2.6.2)
Curtis Yallop
41
Saya punya masalah yang sangat mirip. Tujuannya adalah untuk mengejek layanan yang tetap menggunakan Object dan dapat mengembalikannya dengan nama mereka. Layanannya terlihat seperti ini:
Ini pertanyaan yang cukup lama tapi saya pikir masih relevan. Juga jawaban yang diterima hanya berfungsi untuk String. Sementara itu ada Mockito 2.1 dan beberapa impor telah berubah, jadi saya ingin membagikan jawaban saya saat ini:
importstatic org.mockito.AdditionalAnswers.returnsFirstArg;importstatic org.mockito.ArgumentMatchers.any;importstatic org.mockito.Mockito.when;@MockprivateMyClass myClass;// this will return anything you pass, but it's pretty unrealistic
when(myClass.myFunction(any())).then(returnsFirstArg());// it is more "life-like" to accept only the right type
when(myClass.myFunction(any(ClassOfArgument.class))).then(returnsFirstArg());
Saya menggunakan sesuatu yang serupa (pada dasarnya itu pendekatan yang sama). Kadang-kadang berguna untuk memiliki objek tiruan mengembalikan output yang telah ditentukan untuk input tertentu. Seperti ini:
privateHashtable<InputObject,OutputObject> table =newHashtable<InputObject,OutputObject>();
table.put(input1, ouput1);
table.put(input2, ouput2);...
when(mockObject.method(any(InputObject.class))).thenAnswer(newAnswer<OutputObject>(){@OverridepublicOutputObject answer(finalInvocationOnMock invocation)throwsThrowable{InputObject input =(InputObject) invocation.getArguments()[0];if(table.containsKey(input)){return table.get(input);}else{returnnull;// alternatively, you could throw an exception}}});
Anda mungkin ingin menggunakan verifikasi () dalam kombinasi dengan ArgumentCaptor untuk memastikan eksekusi dalam pengujian dan ArgumentCaptor untuk mengevaluasi argumen:
ArgumentCaptor<String> argument =ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
Nilai argumen jelas dapat diakses melalui argument.getValue () untuk manipulasi lebih lanjut / memeriksa / apa pun.
Ini agak lama, tetapi saya datang ke sini karena saya memiliki masalah yang sama. Saya menggunakan JUnit tetapi kali ini di aplikasi Kotlin dengan mockk. Saya memposting sampel di sini untuk referensi dan perbandingan dengan mitra Java:
@Test
fun demo(){// mock a sample function
val aMock:(String)->(String)= mockk()// make it return the same as the argument on every invocation
every {
aMock.invoke(any())} answers {
firstArg()}// test it
assertEquals("senko", aMock.invoke("senko"))
assertEquals("senko1", aMock.invoke("senko1"))
assertNotEquals("not a senko", aMock.invoke("senko"))}
//Use ArgumentCaptor to capture the valueArgumentCaptor<String> param =ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer(newAnswer<String>(){@OverridepublicString answer(InvocationOnMock invocation)throwsThrowable{return param.getValue();//return the captured value.}});
ATAU jika Anda penggemar lambda cukup lakukan:
//Use ArgumentCaptor to capture the valueArgumentCaptor<String> param =ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer((invocation)-> param.getValue());
Ringkasan: Gunakan argumencaptor, untuk menangkap parameter yang dilewati. Kemudian sebagai jawaban, kembalikan nilai yang ditangkap menggunakan getValue.
Ini tidak berfungsi (lagi?). Mengenai dokumen: Metode ini harus digunakan di dalam verifikasi. Itu berarti Anda hanya dapat menangkap nilai saat menggunakan metode verifikasi
Muhammed Misir
1. Tidak yakin apa yang Anda maksudkan dengan ini This doesn´t work (anymore?).saya bekerja pada contoh saya. 2. Maaf, saya tidak jelas pada poin yang Anda coba buat. Jawabannya khusus untuk pertanyaan OP.
Jawaban:
Anda dapat membuat Jawaban di Mockito. Mari kita asumsikan, kita memiliki antarmuka bernama Aplikasi dengan metode myFunction.
Inilah metode pengujian dengan jawaban Mockito:
Karena Mockito 1.9.5 dan Java 8, Anda juga dapat menggunakan ekspresi lambda:
sumber
when(...).then(Return.firstParameter())
when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class))
. Dan Anda bisa menggunakan referensi metode dan memanggil metode nyata.Iterator<? extends ClassName>
yang menyebabkan semua jenis masalah dalamthenReturn()
pernyataan.when(foo(any()).thenAnswer(i -> i.getArguments()[0])
Jika Anda memiliki Mockito 1.9.5 atau lebih tinggi, ada metode statis baru yang dapat membuat
Answer
objek untuk Anda. Anda perlu menulis sesuatu sepertiatau sebagai alternatif
Perhatikan bahwa
returnsFirstArg()
metode ini statis diAdditionalAnswers
kelas, yang baru untuk Mockito 1.9.5; jadi Anda akan memerlukan impor statis yang tepat.sumber
when(...).then(returnsFirstArg())
, saya keliruwhen(...).thenReturn(returnsFirstArg())
yang memberijava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
static org.mockito.AdditionalAnswers.returnsFirstArg
. ini untuk menggunakan returnsFirstArg. Juga, saya bisa melakukannyawhen(myMock.myFunction(any())).then(returnsFirstArg())
di Mockito 2.20. *Dengan Java 8 dimungkinkan untuk membuat jawaban satu baris bahkan dengan versi Mockito yang lebih lama:
Tentu saja ini tidak berguna seperti yang
AdditionalAnswers
disarankan oleh David Wallace, tetapi mungkin berguna jika Anda ingin mengubah argumen "dengan cepat".sumber
long
, apakah ini masih bisa bekerja dengan tinju danLong.class
?Saya punya masalah yang sangat mirip. Tujuannya adalah untuk mengejek layanan yang tetap menggunakan Object dan dapat mengembalikannya dengan nama mereka. Layanannya terlihat seperti ini:
Mock layanan menggunakan peta untuk menyimpan instance Kamar.
Kami sekarang dapat menjalankan tes kami di mock ini. Sebagai contoh:
sumber
Dengan Java 8, jawaban Steve bisa menjadi
SUNTING: Lebih singkat lagi:
sumber
Ini pertanyaan yang cukup lama tapi saya pikir masih relevan. Juga jawaban yang diterima hanya berfungsi untuk String. Sementara itu ada Mockito 2.1 dan beberapa impor telah berubah, jadi saya ingin membagikan jawaban saya saat ini:
The myClass.myFunction akan terlihat seperti:
sumber
Saya menggunakan sesuatu yang serupa (pada dasarnya itu pendekatan yang sama). Kadang-kadang berguna untuk memiliki objek tiruan mengembalikan output yang telah ditentukan untuk input tertentu. Seperti ini:
sumber
Anda mungkin ingin menggunakan verifikasi () dalam kombinasi dengan ArgumentCaptor untuk memastikan eksekusi dalam pengujian dan ArgumentCaptor untuk mengevaluasi argumen:
Nilai argumen jelas dapat diakses melalui argument.getValue () untuk manipulasi lebih lanjut / memeriksa / apa pun.
sumber
Ini agak lama, tetapi saya datang ke sini karena saya memiliki masalah yang sama. Saya menggunakan JUnit tetapi kali ini di aplikasi Kotlin dengan mockk. Saya memposting sampel di sini untuk referensi dan perbandingan dengan mitra Java:
sumber
Anda dapat mencapai ini dengan menggunakan ArgumentCaptor
Bayangkan Anda memiliki fungsi kacang seperti itu.
Kemudian di kelas ujian Anda:
ATAU jika Anda penggemar lambda cukup lakukan:
Ringkasan: Gunakan argumencaptor, untuk menangkap parameter yang dilewati. Kemudian sebagai jawaban, kembalikan nilai yang ditangkap menggunakan getValue.
sumber
This doesn´t work (anymore?).
saya bekerja pada contoh saya. 2. Maaf, saya tidak jelas pada poin yang Anda coba buat. Jawabannya khusus untuk pertanyaan OP.