Mockito - Menggunakan Spies

1. Ikhtisar

Dalam tutorial ini, kami akan mengilustrasikan cara memaksimalkan mata - mata di Mockito .

Kami akan berbicara tentang anotasi @Spy , cara menghentikan mata-mata, dan akhirnya - kami akan membahas perbedaan antara Mock dan Spy .

Dan tentu saja, untuk kebaikan Mockito lainnya, lihat serinya di sini.

2. Contoh Spy Sederhana

Mari kita mulai dengan contoh sederhana tentang bagaimana menggunakan mata - mata .

Sederhananya, API-nya adalah Mockito.spy () - untuk memata - matai objek nyata .

Ini akan memungkinkan kita memanggil semua metode normal objek sambil tetap melacak setiap interaksi, seperti yang kita lakukan dengan tiruan.

Oke, mari kita lakukan contoh singkat di mana kita akan memata-matai objek ArrayList yang ada :

@Test public void whenSpyingOnList_thenCorrect() { List list = new ArrayList(); List spyList = Mockito.spy(list); spyList.add("one"); spyList.add("two"); Mockito.verify(spyList).add("one"); Mockito.verify(spyList).add("two"); assertEquals(2, spyList.size()); }

Perhatikan bagaimana sebenarnya metode add () dipanggil dan bagaimana ukuran spyList menjadi 2.

3. Anotasi @Spy

Selanjutnya - mari kita lihat cara menggunakan anotasi @Spy . Kita bisa menggunakan anotasi @Spy sebagai pengganti spy () seperti pada contoh berikut:

@Spy List spyList = new ArrayList(); @Test public void whenUsingTheSpyAnnotation_thenObjectIsSpied() { spyList.add("one"); spyList.add("two"); Mockito.verify(spyList).add("one"); Mockito.verify(spyList).add("two"); assertEquals(2, spyList.size()); }

Untuk mengaktifkan anotasi Mockito (seperti @Spy , @Mock ,…) - kita perlu melakukan salah satu hal berikut:

  • Panggil metode MockitoAnnotations.initMocks (this) untuk menginisialisasi kolom beranotasi
  • Gunakan pelari bawaan @RunWith (MockitoJUnitRunner.class)

4. Menonaktifkan Spy

Sekarang - Mari kita lihat bagaimana menghentikan Spy . Kita dapat mengonfigurasi / menimpa perilaku metode menggunakan sintaks yang sama yang akan kita gunakan dengan tiruan.

Dalam contoh berikut - kami menggunakan doReturn () untuk mengganti metode size () :

@Test public void whenStubASpy_thenStubbed() { List list = new ArrayList(); List spyList = Mockito.spy(list); assertEquals(0, spyList.size()); Mockito.doReturn(100).when(spyList).size(); assertEquals(100, spyList.size()); }

5. Mock vs. Spy di Mockito

Sekarang - mari kita bahas perbedaan antara Mock dan Spy di Mockito - bukan perbedaan teoretis antara kedua konsep tersebut, hanya perbedaannya di dalam Mockito itu sendiri.

Saat Mockito membuat tiruan - ia melakukannya dari Class of a Type, bukan dari instance sebenarnya. Tiruan itu hanya membuat contoh cangkang tanpa tulang dari Kelas, sepenuhnya diinstrumentasi untuk melacak interaksi dengannya.

Di sisi lain, mata-mata akan membungkus contoh yang ada . Ini akan tetap berperilaku dengan cara yang sama seperti contoh normal - satu-satunya perbedaan adalah bahwa itu juga akan diinstrumentasi untuk melacak semua interaksi dengannya.

Pada contoh berikut - kami membuat tiruan dari ArrayList kelas:

@Test public void whenCreateMock_thenCreated() { List mockedList = Mockito.mock(ArrayList.class); mockedList.add("one"); Mockito.verify(mockedList).add("one"); assertEquals(0, mockedList.size()); }

Seperti yang bisa kita lihat - menambahkan elemen ke dalam daftar tiruan sebenarnya tidak menambahkan apa pun - itu hanya memanggil metode tanpa efek samping lain.

Seorang mata-mata di sisi lain akan berperilaku berbeda - itu benar-benar akan memanggil implementasi nyata dari add metode dan menambahkan elemen ke daftar mendasari:

@Test public void whenCreateSpy_thenCreate() { List spyList = Mockito.spy(new ArrayList()); spyList.add("one"); Mockito.verify(spyList).add("one"); assertEquals(1, spyList.size()); }

6. Memahami Mockito NotAMockException

Di bagian terakhir ini, kita akan belajar tentang Mockito NotAMockException . Pengecualian ini adalah salah satu pengecualian umum yang mungkin akan kita temui saat menyalahgunakan ejekan atau mata-mata .

Mari kita mulai dengan melihat dalam keadaan apa pengecualian ini dapat terjadi:

List list = new ArrayList(); Mockito.doReturn(100).when(list).size(); assertEquals("Size should be 100: ", 100, list.size()); 

Saat kami menjalankan cuplikan kode ini, kami akan mendapatkan kesalahan berikut:

org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock! Example of correct stubbing: doThrow(new RuntimeException()).when(mock).someMethod(); 

Untungnya dari pesan kesalahan Mockito cukup jelas apa masalahnya di sini. Dalam contoh kami, objek daftar bukan tiruan. Metode Mockito when () mengharapkan objek tiruan atau mata-mata sebagai argumen .

Seperti yang kita juga dapat melihat pesan Exception bahkan menjelaskan seperti apa permintaan yang benar seharusnya. Sekarang kita memiliki pemahaman yang lebih baik tentang apa masalahnya, mari kita perbaiki dengan mengikuti rekomendasi:

final List spyList = Mockito.spy(new ArrayList()); Mockito.doReturn(100).when(spyList).size(); assertEquals("Size should be 100: ", 100, spyList.size()); 

Contoh kita sekarang berperilaku seperti yang diharapkan dan kita tidak lagi melihat Mockito NotAMockException.

7. Kesimpulan

Dalam artikel singkat ini, kami membahas contoh paling berguna dari penggunaan mata-mata Mockito.

Kami belajar cara membuat mata - mata , cara menggunakan anotasi @Spy , cara menghentikan mata - mata , dan, terakhir - perbedaan antara Mock dan Spy .

Penerapan semua contoh ini dapat ditemukan di GitHub .

Ini adalah proyek Maven, jadi semestinya mudah untuk mengimpor dan menjalankannya apa adanya.

Dan tentu saja, untuk kebaikan Mockito lainnya, lihat serinya di sini.