Mockito.any () lulus Interface dengan Generics

170

apakah mungkin untuk melewatkan jenis antarmuka dengan obat generik?

Antarmuka:

public interface AsyncCallback<T>

Dalam metode pengujian saya:

Mockito.any(AsyncCallback.class)

Menempatkan di <ResponseX>belakang atau untuk .classtidak berhasil.

lrxw
sumber

Jawaban:

306

Ada cara yang aman untuk mengetik: gunakan ArgumentMatchers.any()dan beri kualifikasi dengan jenisnya:

ArgumentMatchers.<AsyncCallback<ResponseX>>any()
thSoft
sumber
4
Saya mengkonfirmasi jawaban ini berfungsi dan benar menekan peringatan.
kevinarpe
1
Ini sebenarnya tidak lebih aman karena metode aktual hanya dapat dipanggil dengan argumen yang diketik dengan benar. Itu hanya perlu untuk memenuhi compiler pra-java8 yang tidak memiliki inferensi jenis ini.
herman
Saya menggunakan sesuatu seperti ini ResponseEntity <Daftar <Peta <String, Objek >>> responseEntity = Pencocokan. <ResponseEntity <Daftar <Peta <String, Objek >>>> any (); Dan selalu mengembalikan nol
Arun
6
Dengan versi baru Mockito:(Matchers.<AsyncCallback<ResponseX>>any()
pierrefevrier
15
Matcherssebenarnya sudah usang, tetapi ArgumentMatchersberhasil.
guijob
67

Menggunakan Java 8, Anda cukup menggunakan any()(dengan asumsi impor statis) tanpa parameter argumen atau tipe karena inferensi tipe yang ditingkatkan. Kompiler sekarang tahu dari tipe target (tipe argumen metode) yang sebenarnya Anda maksud Matchers.<AsyncCallback<ResponseX>>any(), yang merupakan solusi pra-Java 8.

herman
sumber
Tidak akan any()cocok AsyncCallback<AnyOtherType>juga?
Matius Baca
@MatthewRead Menggunakan AsyncCallback<AnyOtherType>bahkan tidak harus mengkompilasi jika tipe argumen adalah 'AsyncCallback <ResponseX>'.
herman
1
Saya bertanya-tanya tentang situasi di mana tipe argumen generik juga, tetapi Anda hanya ingin mengejeknya untuk satu tipe konkret (atau mengejeknya untuk beberapa jenis dengan cara yang berbeda). Mengingat when(x.y(any())).thenAnswer(...)misalnya, di mana yadalah public <T> T y(AsyncCallback<T> arg). Mungkin akan lebih baik untuk memeriksa jenis jawaban, jika itu yang dibutuhkan?
Matius Baca
2
@ MatthewRead Karena penghapusan, tipe yang sebenarnya tidak dapat diperiksa saat runtime oleh Mockito. Jadi Anda bahkan tidak bisa menggunakannya isA(). Jika objek memegang Classobjek yang sesuai dengan jenisnya, dan antarmuka mengekspos ini, saya kira Anda bisa memeriksanya di pencocokan kustom. Atau misalnya dalam kasus CollectionAnda dapat memeriksa jenis elemen.
herman
1
Matchersdigantikan oleh ArgumentMatchersdi Mockito v2
bheussler
15

Saya harus mengadopsi mekanisme berikut untuk memungkinkan obat generik:

import static org.mockito.Matchers.any;
List<String> list = any();
when(callMyMethod.getResult(list)).thenReturn(myResultString);

Semoga ini bisa membantu seseorang.

theINtoy
sumber
3
Lihat jawaban saya: ini tidak lagi diperlukan dengan Java 8.
herman
5

Posting komentar pierrefevrier sebagai jawaban yang mungkin berguna jika ada dalam jawaban, bukan komentar.

Dengan versi baru Mockito: (Matchers.<AsyncCallback<ResponseX>>any()

melengkung
sumber
1
saya menambahkan komentarnya ke jawaban aslinya
Joergi
2

Lebih jauh ke jawaban thSoft menempatkan panggilan yang memenuhi syarat ke () dalam metode berarti saya bisa menghapus kualifikasi karena jenis pengembalian inferensi diperbolehkan:

private HashMap<String, String> anyStringStringHashMap() {
    return Matchers.any();
}
JWGS
sumber
0

Anda bisa melemparkannya, menambahkan peringatan penekan jika Anda suka:

@SuppressWarnings("unchecked")    
AsyncCallback<ResponseX> callback = Mockito.any(AsyncCallback.class)

Jika Java memperbolehkan generik 'generik' mereka dapat memiliki metode seperti ini yang Anda cari

private static <T, E> T<E> mock(Class<T<E>> clazz)
Garrett Hall
sumber
Ketika saya mencoba ini, saya menerima kesalahan dalam pengujian saya:You cannot use argument matchers outside of verification or stubbing.
kevinarpe
Bukan ide yang baik untuk digunakan @SuppressWarnings: pra-java 8, jika Anda akan menetapkannya ke variabel yang terpisah, Anda bisa menggunakannya any()seperti pada jawaban theINtoy. Sekarang dengan java 8, any()dapat digunakan inline tanpa perlu tugas yang terpisah.
herman
@ kevinarpe jika Anda memiliki beberapa pencocokan argumen, mereka harus dipanggil agar ditentukan oleh bahasa Java.
TWiStErRob
0

Saya punya masalah serupa menggunakan Spring Example:

Mockito.when(repo.findAll(Mockito.<Example<SrvReqToSupplierComment>>any()))
            .thenReturn(Lists.emptyList());

Di sini, Anda harus menggunakan kualifikasi, b / c metode findAll dapat mengambil beberapa jenis, seperti Sortdan Iterable. Anda juga dapat menggunakan Mockito.any(Example.class)tentu saja dengan jenis peringatan keselamatan.

gagarwa
sumber