Menguji Callback dengan Mockito

1. Ikhtisar

Dalam tutorial singkat ini, kami akan fokus pada cara menguji Callback menggunakan kerangka pengujian populer Mockito.

Kami akan mengeksplorasi dua solusi, pertama menggunakan ArgumentCaptor dan kemudian intuitif doAnswer () metode .

Untuk mempelajari lebih lanjut tentang menguji dengan baik dengan Mockito, lihat seri Mockito kami di sini.

2. Pengantar Callback

Callback adalah potongan kode yang diteruskan sebagai argumen ke metode, yang diharapkan untuk memanggil kembali (mengeksekusi) argumen pada waktu tertentu .

Eksekusi ini mungkin terjadi secara langsung seperti pada callback sinkron, tetapi lebih seringnya bisa terjadi di lain waktu seperti pada callback asinkron.

Skenario umum untuk penggunaan Callback adalah selama interaksi layanan saat kita perlu memproses respons dari panggilan layanan .

Dalam tutorial ini, kami akan menggunakan antarmuka Layanan yang ditunjukkan di bawah ini sebagai kolaborator dalam kasus uji:

public interface Service { void doAction(String request, Callback callback); }

Dalam argumen Callback kita melewatkan kelas yang akan menangani respon menggunakan metode reply (T response) :

public interface Callback { void reply(T response); } 

2.1. Sebuah Layanan Sederhana

Kami juga akan menggunakan contoh layanan langsung untuk mendemonstrasikan cara meneruskan dan memanggil callback :

public void doAction() { service.doAction("our-request", new Callback() { @Override public void reply(Response response) { handleResponse(response); } }); } 

The handleResponse Metode pemeriksaan untuk melihat apakah respon tersebut valid sebelum menambahkan beberapa data ke Response objek:

private void handleResponse(Response response) { if (response.isValid()) { response.setData(new Data("Successful data response")); } }

Untuk kejelasan, kami memilih untuk tidak menggunakan ekspresi Java Lamda tetapi panggilan service.doAction juga dapat ditulis lebih ringkas :

service.doAction("our-request", response -> handleResponse(response)); 

Untuk mempelajari lebih lanjut tentang ekspresi Lambda, lihat di sini.

3. Menggunakan ArgumentCaptor

Sekarang mari kita lihat bagaimana kita menggunakan Mockito untuk mengambil objek Callback menggunakan ArgumentCaptor :

@Test public void givenServiceWithValidResponse_whenCallbackReceived_thenProcessed() { ActionHandler handler = new ActionHandler(service); handler.doAction(); verify(service).doAction(anyString(), callbackCaptor.capture()); Callback callback = callbackCaptor.getValue(); Response response = new Response(); callback.reply(response); String expectedMessage = "Successful data response"; Data data = response.getData(); assertEquals( "Should receive a successful message: ", expectedMessage, data.getMessage()); }

Dalam contoh ini, pertama kita membuat ActionHandler sebelum memanggil metode doAction dari handler ini. Ini hanyalah pembungkus untuk panggilan metode doAction Layanan Sederhana kami yang mana kami memanggil callback kami.

Selanjutnya, kami memverifikasi bahwa doAction dipanggil pada instance layanan tiruan kami dengan meneruskan anyString () sebagai argumen pertama dan callbackCaptor.capture () sebagai argumen kedua, yang merupakan tempat kami menangkap objek Callback . Metode getValue () kemudian bisa digunakan untuk mengembalikan nilai yang ditangkap dari argumen.

Sekarang kita telah mendapatkan objek Callback , kita membuat objek Respon yang valid secara default sebelum kita memanggil metode reply secara langsung dan menegaskan bahwa data respon memiliki nilai yang benar .

4. Menggunakan Metode doAnswer ()

Sekarang kita akan melihat solusi umum untuk metode stub yang memiliki callback menggunakan objek Answer Mockito dan metode doAnswer untuk menghentikan metode void doAction:

@Test public void givenServiceWithInvalidResponse_whenCallbackReceived_thenNotProcessed() { Response response = new Response(); response.setIsValid(false); doAnswer((Answer) invocation -> { Callback callback = invocation.getArgument(1); callback.reply(response); Data data = response.getData(); assertNull("No data in invalid response: ", data); return null; }).when(service) .doAction(anyString(), any(Callback.class)); ActionHandler handler = new ActionHandler(service); handler.doAction(); } 

Dan, dalam contoh kedua kami, pertama-tama kami membuat objek Respons yang tidak valid yang akan digunakan nanti dalam pengujian.

Selanjutnya, kami menyiapkan Answer pada layanan tiruan kami sehingga ketika doAction dipanggil, kami mencegat pemanggilan dan mengambil argumen metode menggunakan invocation.getArgument (1) untuk mendapatkan argumen Callback .

Langkah terakhir adalah membuat ActionHandler dan memanggil doAction yang menyebabkan Answer dipanggil.

Untuk mempelajari lebih lanjut tentang metode stubbing void, lihat di sini.

3. Kesimpulan

Dalam artikel singkat ini, kami membahas dua cara berbeda untuk mendekati pengujian callback saat menguji dengan Mockito.

Seperti biasa, contoh tersedia di proyek GitHub ini.