Mockito ArgumentMatchers

1. Ikhtisar

Tutorial ini menunjukkan cara menggunakan ArgumentMatcher dan perbedaannya dari ArgumentCaptor .

Untuk pengantar kerangka kerja Mockito, silakan lihat artikel ini.

2. Ketergantungan Maven

Kita perlu menambahkan satu artefak:

 org.mockito mockito-core 2.21.0 test 

Versi terbaru Mockito dapat ditemukan di Maven Central .

3. ArgumentMatchers

Mengonfigurasi metode tiruan dengan berbagai cara dimungkinkan. Salah satunya adalah mengembalikan nilai tetap:

doReturn("Flower").when(flowerService).analyze("poppy");

Dalam contoh di atas, String "Bunga" dikembalikan hanya ketika layanan analisis menerima String "poppy".

Tapi mungkin kita perlu menanggapi nilai yang lebih luas atau nilai yang sebelumnya tidak diketahui .

Dalam semua skenario ini, kami dapat mengonfigurasi metode tiruan kami dengan pencocok argumen :

when(flowerService.analyze(anyString())).thenReturn("Flower");

Sekarang, karena pencocok argumen anyString , hasilnya akan sama tidak peduli berapa nilai yang kita berikan untuk dianalisis. ArgumentMatchers memungkinkan kami melakukan verifikasi atau penghentian yang fleksibel.

Jika suatu metode memiliki lebih dari satu argumen, tidak mungkin menggunakan ArgumentMatchers hanya untuk beberapa argumen . Mockito mengharuskan Anda memberikan semua argumen baik dengan pencocokan atau dengan nilai persis.

Contoh selanjutnya adalah pendekatan yang salah untuk ini:

abstract class FlowerService { public abstract boolean isABigFlower(String name, int petals); } FlowerService mock = mock(FlowerService.class); when(mock.isABigFlower("poppy", anyInt())).thenReturn(true);

Untuk memperbaikinya dan mempertahankan nama String "poppy" seperti yang diinginkan, kita akan menggunakan eq matcher :

when(mock.isABigFlower(eq("poppy"), anyInt())).thenReturn(true);

Ada dua poin lagi yang harus diperhatikan saat matcher digunakan:

  • Kami tidak dapat menggunakannya sebagai nilai pengembalian , nilai yang tepat diperlukan saat menghentikan panggilan
  • Terakhir, kami tidak dapat menggunakan pencocok argumen di luar verifikasi atau stubbing

Dalam kasus terakhir, Mockito akan mendeteksi argumen yang salah tempat dan menampilkan InvalidUseOfMatchersException .

Contoh yang buruk bisa jadi:

String orMatcher = or(eq("poppy"), endsWith("y")); verify(mock).analyze(orMatcher);

Cara mengimplementasikan kode di atas adalah:

verify(mock).analyze(or(eq("poppy"), endsWith("y")));

Mockito juga menyediakan AdditionalMatchers untuk mengimplementasikan operasi logika umum ('not', 'and', 'or') pada ArgumentMatchers yang cocok dengan tipe primitif dan non-primitif:

verify(mock).analyze(or(eq("poppy"), endsWith("y")));

4. Pencocokan Argumen Kustom

Membuat pencocokan kami dapat menjadi cara yang baik untuk memilih pendekatan terbaik untuk skenario tertentu dan menghasilkan pengujian kualitas tertinggi , yang bersih dan dapat dipelihara.

Misalnya, kita bisa memiliki MessageController yang mengirimkan pesan. Ini akan menerima MessageDTO , dan dari itu, Ini akan membuat Pesan untuk dikirim oleh MessageService .

Verifikasi kami akan sederhana, verifikasi bahwa kami memanggil MessageService tepat 1 kali dengan Pesan apa pun:

verify(messageService, times(1)).deliverMessage(any(Message.class));

Karena itu Pesan dibangun dalam metode yang diuji , kita dipaksa untuk menggunakan setiap sebagai pencocok .

Pendekatan ini tidak memungkinkan kami memvalidasi data di dalam Message , yang dapat berbeda dibandingkan dengan data di dalam MessageDTO .

Untuk alasan itu, kami akan menerapkan pencocokan argumen khusus:

public class MessageMatcher implements ArgumentMatcher { private Message left; // constructors @Override public boolean matches(Message right) { return left.getFrom().equals(right.getFrom()) && left.getTo().equals(right.getTo()) && left.getText().equals(right.getText()) && right.getDate() != null && right.getId() != null; } }

Untuk menggunakan matcher kita, kita perlu memodifikasi pengujian kita dan mengganti apapun dengan argThat :

verify(messageService, times(1)).deliverMessage(argThat(new MessageMatcher(message)));

Sekarang kita tahu instance Message kita akan memiliki data yang sama dengan MessageDTO kita .

5. Pencocokan Argumen Kustom vs. ArgumentCaptor

Kedua teknik pencocok argumen khusus dan ArgumentCaptor dapat digunakan untuk memastikan argumen tertentu diteruskan ke tiruan.

Namun, ArgumentCaptor mungkin lebih cocok jika kita membutuhkannya untuk menegaskan nilai argumen untuk menyelesaikan verifikasi atau pencocok argumen khusus kita tidak mungkin digunakan kembali .

Pencocok argumen khusus melalui ArgumentMatcher biasanya lebih baik untuk stub.

6. Kesimpulan

Di artikel ini, kita telah mempelajari fitur Mockito , ArgumentMatcher dan perbedaannya dengan ArgumentCaptor .

Seperti biasa, kode sumber lengkap dari contoh tersedia di GitHub.