Mockito ArgumentMatchers

1. Gambaran keseluruhan

Tutorial ini menunjukkan cara menggunakan ArgumentMatcher dan bagaimana ia berbeza dengan ArgumentCaptor .

Untuk pengenalan kerangka kerja Mockito, rujuk artikel ini.

2. Pergantungan Maven

Kita perlu menambah satu artifak:

 org.mockito mockito-core 2.21.0 test 

Versi terbaru Mockito boleh didapati di Maven Central .

3. ArgumentMatchers

Mengkonfigurasi kaedah ejekan dengan pelbagai cara adalah mungkin. Salah satunya adalah mengembalikan nilai tetap:

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

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

Tetapi mungkin kita perlu bertindak balas terhadap nilai yang lebih luas atau nilai yang tidak diketahui sebelumnya .

Dalam semua senario ini, kita dapat mengkonfigurasi kaedah olok-olok kita dengan pencocokan argumen :

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

Sekarang, kerana pencocokan argumen anyString , hasilnya akan sama tidak kira apa nilai yang kita lalui untuk dianalisis. ArgumentMatchers membolehkan kami membuat pengesahan atau penegasan yang fleksibel.

Sekiranya kaedah mempunyai lebih dari satu argumen, tidak mungkin menggunakan ArgumentMatchers hanya untuk beberapa argumen . Mockito menghendaki anda memberikan semua hujah sama ada oleh pemadan atau dengan nilai yang tepat.

Contoh seterusnya 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 menyimpan nama String "poppy" seperti yang diinginkan, kami akan menggunakan eq matcher :

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

Terdapat dua perkara lagi yang perlu diberi perhatian semasa pemadan digunakan:

  • Kami tidak dapat menggunakannya sebagai nilai pengembalian , diperlukan nilai yang tepat ketika menghentikan panggilan
  • Akhirnya, kami tidak dapat menggunakan pencocokan argumen di luar pengesahan atau stubing

Dalam kes terakhir, Mockito akan mengesan argumen yang salah tempat dan membuang InvalidUseOfMatchersException .

Contoh buruk ialah:

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

Cara untuk melaksanakan kod di atas adalah:

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

Mockito juga menyediakan TambahanMatchers untuk melaksanakan operasi logik biasa ('tidak', 'dan', 'atau') pada ArgumentMatchers yang sesuai dengan jenis primitif dan bukan primitif:

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

4. Pemadan Argumen Custom

Membuat pencocokan kita boleh memilih pendekatan terbaik untuk senario tertentu dan menghasilkan ujian kualiti tertinggi , yang bersih dan dapat dipelihara.

Sebagai contoh, kita boleh mempunyai MessageController yang menyampaikan mesej. Ia akan menerima MessageDTO , dan dari itu, Ia akan membuat Mesej yang akan dihantar oleh MessageService .

Pengesahan kami akan mudah, sahkan bahawa kami memanggil MessageService tepat 1 kali dengan mana - mana Mesej:

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

Kerana yang Mesej dibina dalam kaedah di bawah ujian , kami terpaksa menggunakan apa-apa sebagai matcher .

Pendekatan ini tidak memungkinkan kita mengesahkan data di dalam Pesan , yang boleh berbeza dengan data di dalam MessageDTO .

Oleh sebab itu, kami akan menerapkan pemadan 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 untuk mengubah suai ujian kami dan menggantikan mana-mana oleh argThat :

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

Sekarang kita tahu contoh Mesej kita akan mempunyai data yang sama dengan MessageDTO kita .

5. Custom Argument Matcher vs ArgumentCaptor

Kedua-dua teknik pemadan argumen khusus dan ArgumentCaptor dapat digunakan untuk memastikan argumen tertentu disampaikan kepada ejekan.

Walau bagaimanapun, ArgumentCaptor mungkin lebih sesuai jika kita memerlukannya untuk menegaskan nilai argumen untuk menyelesaikan pengesahan atau pemadan argumen khusus kita tidak mungkin akan digunakan kembali .

Pencocokan argumen khusus melalui ArgumentMatcher biasanya lebih baik untuk menyekat.

6. Kesimpulannya

Dalam artikel ini, kami telah meneroka ciri Mockito , ArgumentMatcher dan perbezaannya dengan ArgumentCaptor .

Seperti biasa, kod sumber penuh contoh terdapat di GitHub.