Pengantar PowerMock

1. Ikhtisar

Pengujian unit dengan bantuan kerangka kerja tiruan telah diakui sebagai praktik yang berguna sejak lama, dan kerangka kerja Mockito, khususnya, telah mendominasi pasar ini dalam beberapa tahun terakhir.

Dan untuk memfasilitasi desain kode yang layak dan membuat API publik sederhana, beberapa fitur yang diinginkan sengaja ditinggalkan. Namun, dalam beberapa kasus, kekurangan ini memaksa penguji untuk menulis kode yang rumit hanya untuk membuat pembuatan tiruan menjadi layak.

Di sinilah kerangka PowerMock berperan.

PowerMockito adalah API ekstensi PowerMock untuk mendukung Mockito. Ini memberikan kemampuan untuk bekerja dengan Java Reflection API dengan cara sederhana untuk mengatasi masalah Mockito, seperti kurangnya kemampuan untuk meniru metode final, statis, atau pribadi.

Tutorial ini akan memberikan pengenalan tentang PowerMockito API dan bagaimana itu diterapkan dalam pengujian.

2. Mempersiapkan Pengujian Dengan PowerMockito

Langkah pertama untuk mengintegrasikan dukungan PowerMock untuk Mockito adalah menyertakan dua dependensi berikut di file POM Maven:

 org.powermock powermock-module-junit4 1.6.4 test   org.powermock powermock-api-mockito 1.6.4 test 

Selanjutnya, kita perlu menyiapkan kasus pengujian untuk bekerja dengan PowerMockito dengan menerapkan dua anotasi berikut:

@RunWith(PowerMockRunner.class) @PrepareForTest(fullyQualifiedNames = "com.baeldung.powermockito.introduction.*")

The fullyQualifiedNames elemen dalam @PrepareForTest penjelasan mewakili array nama yang memenuhi syarat dari jenis kami ingin mengejek. Dalam kasus ini, kami menggunakan nama paket dengan karakter pengganti untuk memberi tahu PowerMockito agar menyiapkan semua jenis dalam paket com.baeldung.powermockito.introduction untuk pembuatan tiruan.

Sekarang kami siap untuk memanfaatkan kekuatan PowerMockito .

3. Mengejek Konstruktor dan Metode Akhir

Di bagian ini, kita akan mendemonstrasikan cara untuk mendapatkan contoh tiruan daripada yang asli saat membuat instance kelas dengan operator baru , dan kemudian menggunakan objek itu untuk meniru metode terakhir. Kelas kolaborasi, yang konstruktor dan metode akhirnya akan diolok-olok, didefinisikan sebagai berikut:

public class CollaboratorWithFinalMethods { public final String helloMethod() { return "Hello World!"; } }

Pertama, kami membuat objek tiruan menggunakan PowerMockito API:

CollaboratorWithFinalMethods mock = mock(CollaboratorWithFinalMethods.class);

Selanjutnya, setel ekspektasi yang mengatakan bahwa setiap kali konstruktor no-arg dari kelas itu dipanggil, instance tiruan harus dikembalikan daripada yang asli:

whenNew(CollaboratorWithFinalMethods.class).withNoArguments().thenReturn(mock);

Mari kita lihat cara kerja pemalsuan konstruksi ini dengan membuat instance kelas CollaboratorWithFinalMethods menggunakan konstruktor defaultnya, lalu memverifikasi perilaku PowerMock:

CollaboratorWithFinalMethods collaborator = new CollaboratorWithFinalMethods(); verifyNew(CollaboratorWithFinalMethods.class).withNoArguments();

Pada langkah berikutnya, ekspektasi ditetapkan ke metode terakhir:

when(collaborator.helloMethod()).thenReturn("Hello Baeldung!");

Metode ini kemudian dijalankan:

String welcome = collaborator.helloMethod();

Pernyataan berikut mengonfirmasi bahwa metode helloMethod telah dipanggil pada objek kolaborator , dan mengembalikan nilai yang ditetapkan oleh ekspektasi tiruan:

Mockito.verify(collaborator).helloMethod(); assertEquals("Hello Baeldung!", welcome);

Jika kita ingin mengejek metode akhir tertentu daripada semua yang terakhir di dalam sebuah objek, metode Mockito.spy (T object) mungkin berguna. Ini diilustrasikan di bagian 5.

4. Metode Statis Mengejek

Misalkan kita ingin membuat tiruan metode statis dari kelas bernama CollaboratorWithStaticMethods. Kelas ini dideklarasikan sebagai berikut:

public class CollaboratorWithStaticMethods { public static String firstMethod(String name) { return "Hello " + name + " !"; } public static String secondMethod() { return "Hello no one!"; } public static String thirdMethod() { return "Hello no one again!"; } }

Untuk meniru metode statis ini, kita perlu mendaftarkan kelas penutup dengan PowerMockito API:

mockStatic(CollaboratorWithStaticMethods.class);

Alternatifnya, kita dapat menggunakan metode Mockito.spy (Class class) untuk mengejek metode tertentu seperti yang ditunjukkan di bagian berikut.

Selanjutnya, ekspektasi dapat diatur untuk menentukan metode nilai yang harus dikembalikan saat dipanggil:

when(CollaboratorWithStaticMethods.firstMethod(Mockito.anyString())) .thenReturn("Hello Baeldung!"); when(CollaboratorWithStaticMethods.secondMethod()).thenReturn("Nothing special");

Atau pengecualian mungkin disetel untuk dilemparkan saat memanggil metode thirdMethod :

doThrow(new RuntimeException()).when(CollaboratorWithStaticMethods.class); CollaboratorWithStaticMethods.thirdMethod();

Sekarang, saatnya untuk menjalankan dua metode pertama:

String firstWelcome = CollaboratorWithStaticMethods.firstMethod("Whoever"); String secondWelcome = CollaboratorWithStaticMethods.firstMethod("Whatever");

Alih-alih memanggil anggota kelas nyata, pemanggilan di atas didelegasikan ke metode tiruan. Penegasan berikut membuktikan bahwa tiruan telah berlaku:

assertEquals("Hello Baeldung!", firstWelcome); assertEquals("Hello Baeldung!", secondWelcome);

Kami juga dapat memverifikasi perilaku metode tiruan, termasuk berapa kali metode dipanggil. Dalam hal ini, firstMethod telah dipanggil dua kali, sedangkan secondMethod tidak pernah:

verifyStatic(Mockito.times(2)); CollaboratorWithStaticMethods.firstMethod(Mockito.anyString()); verifyStatic(Mockito.never()); CollaboratorWithStaticMethods.secondMethod();

Catatan: The verifyStatic Metode harus dipanggil tepat sebelum verifikasi metode statis untuk PowerMockito tahu bahwa metode berturut doa adalah apa yang perlu diverifikasi.

Terakhir, metode thirdMethod statis harus menampilkan RuntimeException seperti yang dideklarasikan pada tiruan sebelumnya. Ini divalidasi oleh elemen yang diharapkan dari anotasi @Test :

@Test(expected = RuntimeException.class) public void givenStaticMethods_whenUsingPowerMockito_thenCorrect() { // other methods CollaboratorWithStaticMethods.thirdMethod(); }

5. Mengolok-olok Parsial

Alih-alih mengejek seluruh kelas, PowerMockito API memungkinkan untuk mengejek sebagian darinya menggunakan metode mata - mata . Kelas berikut akan digunakan sebagai kolaborator untuk mengilustrasikan dukungan PowerMock untuk penghinaan parsial:

public class CollaboratorForPartialMocking { public static String staticMethod() { return "Hello Baeldung!"; } public final String finalMethod() { return "Hello Baeldung!"; } private String privateMethod() { return "Hello Baeldung!"; } public String privateMethodCaller() { return privateMethod() + " Welcome to the Java world."; } }

Mari kita mulai dengan membuat tiruan metode statis, yang bernama staticMethod dalam definisi kelas di atas. Pertama, gunakan PowerMockito API untuk meniru sebagian kelas CollaboratorForP PartialMocking dan menyetel ekspektasi untuk metode statisnya:

spy(CollaboratorForPartialMocking.class); when(CollaboratorForPartialMocking.staticMethod()).thenReturn("I am a static mock method.");

Metode statis kemudian dijalankan:

returnValue = CollaboratorForPartialMocking.staticMethod();

Perilaku mengejek diverifikasi sebagai berikut:

verifyStatic(); CollaboratorForPartialMocking.staticMethod();

Penegasan berikut mengonfirmasi bahwa metode tiruan sebenarnya telah dipanggil dengan membandingkan nilai yang dikembalikan dengan yang diharapkan:

assertEquals("I am a static mock method.", returnValue);

Sekarang saatnya beralih ke metode final dan privat. Untuk mengilustrasikan pemalsuan sebagian dari metode ini, kita perlu membuat instance kelas dan memberi tahu PowerMockito API untuk memata - matai :

CollaboratorForPartialMocking collaborator = new CollaboratorForPartialMocking(); CollaboratorForPartialMocking mock = spy(collaborator);

The objects created above are used to demonstrating the mocking of both the final and private methods. We will deal with the final method now by setting an expectation and invoke the method:

when(mock.finalMethod()).thenReturn("I am a final mock method."); returnValue = mock.finalMethod();

The behavior of partially mocking that method is proved:

Mockito.verify(mock).finalMethod();

A test verifies that calling the finalMethod method will return a value that matches the expectation:

assertEquals("I am a final mock method.", returnValue);

A similar process is applied to the private method. The main difference is that we cannot directly invoke this method from the test case. Basically, a private method is to be called by other ones from the same class. In the CollaboratorForPartialMocking class, the privateMethod method is to be invoked by the privateMethodCaller method and we will use the latter as a delegate. Let's start with the expectation and invocation:

when(mock, "privateMethod").thenReturn("I am a private mock method."); returnValue = mock.privateMethodCaller();

The mocking of the private method is confirmed:

verifyPrivate(mock).invoke("privateMethod");

The following test makes sure that the return value from invocation of the private method is the same as the expectation:

assertEquals("I am a private mock method. Welcome to the Java world.", returnValue);

6. Conclusion

Tutorial ini telah memberikan pengantar ke PowerMockito API, mendemonstrasikan penggunaannya dalam memecahkan beberapa masalah yang ditemui pengembang saat menggunakan kerangka kerja Mockito.

Penerapan contoh dan cuplikan kode ini dapat ditemukan di proyek GitHub yang ditautkan.