Pengenalan PowerMock

1. Gambaran keseluruhan

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

Dan untuk memudahkan reka bentuk kod yang baik dan menjadikan API awam mudah, beberapa ciri yang diinginkan sengaja ditinggalkan. Walau bagaimanapun, dalam beberapa kes, kekurangan ini memaksa penguji untuk menulis kod yang rumit untuk membuat penciptaan ejekan.

Di sinilah kerangka PowerMock dimainkan.

PowerMockito adalah API sambungan PowerMock untuk menyokong Mockito. Ini memberikan kemampuan untuk bekerja dengan Java Reflection API dengan cara mudah untuk mengatasi masalah Mockito, seperti kurangnya kemampuan untuk mengejek kaedah akhir, statik atau swasta.

Tutorial ini akan memberi pengenalan kepada API PowerMockito dan bagaimana ia diterapkan dalam ujian.

2. Bersedia untuk Menguji Dengan PowerMockito

Langkah pertama untuk menyatukan sokongan PowerMock untuk Mockito adalah memasukkan dua kebergantungan berikut dalam fail POM Maven:

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

Seterusnya, kita perlu menyediakan kes ujian untuk bekerja dengan PowerMockito dengan menerapkan dua anotasi berikut:

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

The fullyQualifiedNames unsur dalam @PrepareForTest anotasi mewakili pelbagai nama-nama yang berkelayakan sepenuhnya jenis kita mahu-olokkan itu. Dalam kes ini, kami menggunakan nama pakej dengan wildcard untuk memberitahu PowerMockito untuk menyediakan semua jenis dalam pakej pengenalan com.baeldung.powermockito.intejek .

Sekarang kita bersedia untuk mengeksploitasi kekuatan PowerMockito .

3. Konstruktor Mengejek dan Kaedah Akhir

Di bahagian ini, kami akan menunjukkan cara-cara untuk mendapatkan contoh tiruan dan bukan yang nyata ketika membuat kelas dengan operator baru , dan kemudian menggunakan objek itu untuk mengejek kaedah terakhir. Kelas bekerjasama, yang konstruktor dan kaedah terakhir akan diejek, ditakrifkan 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);

Seterusnya, tetapkan jangkaan yang mengatakan bahawa setiap kali konstruktor no-arg kelas itu dipanggil, contoh tiruan harus dikembalikan daripada yang sebenarnya:

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

Mari lihat bagaimana ejekan pembinaan ini berfungsi dengan memberi kesan kepada kelas CollaboratorWithFinalMethods menggunakan konstruktor lalai, dan kemudian mengesahkan tingkah laku PowerMock:

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

Pada langkah seterusnya, jangkaan ditetapkan ke kaedah terakhir:

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

Kaedah ini kemudian dijalankan:

String welcome = collaborator.helloMethod();

Tegasan berikut mengesahkan bahawa kaedah helloMethod telah dipanggil pada objek kolaborator , dan mengembalikan nilai yang ditetapkan oleh harapan mengejek:

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

Sekiranya kita ingin mengejek kaedah akhir tertentu daripada semua kaedah akhir di dalam objek, kaedah Mockito.spy (objek T) mungkin berguna. Ini digambarkan dalam bahagian 5.

4. Kaedah Statik Mengejek

Anggaplah kita mahu memperolokkan kaedah statik kelas bernama CollaboratorWithStaticMethods. Kelas ini dinyatakan seperti 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 mengejek kaedah statik ini, kita perlu mendaftarkan kelas lampiran dengan PowerMockito API:

mockStatic(CollaboratorWithStaticMethods.class);

Sebagai alternatif, kami mungkin menggunakan kaedah Mockito.spy (Kelas kelas) untuk mengejek kaedah tertentu seperti yang ditunjukkan dalam bahagian berikut.

Seterusnya, jangkaan dapat ditetapkan untuk menentukan kaedah nilai yang harus dikembalikan apabila dipanggil:

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

Atau pengecualian mungkin akan dilemparkan ketika memanggil kaedah Metode ketiga :

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

Sekarang, sudah tiba masanya untuk melaksanakan dua kaedah pertama:

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

Daripada memanggil ahli kelas sebenar, ajakan di atas diberikan kepada kaedah ejekan. Penegasan berikut membuktikan bahawa ejekan telah berlaku:

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

Kami juga dapat mengesahkan tingkah laku kaedah olok-olok, termasuk berapa kali kaedah digunakan. Dalam kes ini, Metode pertama telah dipanggil dua kali, sementara Metode kedua tidak pernah:

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

Nota: The verifyStatic kaedah mesti dipanggil betul sebelum mana-mana pengesahan kaedah statik untuk PowerMockito tahu bahawa berturut-kaedah doa adalah apa yang perlu disahkan.

Terakhir, kaedah ketiga Metode statik harus melemparkan RuntimeException seperti yang dinyatakan pada tiruan sebelumnya. Ia disahkan oleh elemen yang diharapkan dari anotasi @Test :

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

5. Mengejek Sebahagian

Daripada mengejek seluruh kelas, PowerMockito API memungkinkan untuk mengejek sebahagiannya menggunakan kaedah pengintipan . Kelas berikut akan digunakan sebagai kolaborator untuk menggambarkan sokongan PowerMock untuk ejekan separa:

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 mulakan dengan mengejek kaedah statik, yang dinamakan staticMethod dalam definisi kelas di atas. Pertama, gunakan PowerMockito API untuk mengejek sebahagian kelas CollaboratorForPartialMocking dan menetapkan jangkaan kaedah statiknya:

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

Kaedah statik kemudian dijalankan:

returnValue = CollaboratorForPartialMocking.staticMethod();

Tingkah laku mengejek disahkan seperti berikut:

verifyStatic(); CollaboratorForPartialMocking.staticMethod();

Tegasan berikut mengesahkan bahawa kaedah tiruan sebenarnya telah dipanggil dengan membandingkan nilai pulangan dengan jangkaan:

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

Kini tiba masanya untuk beralih ke kaedah terakhir dan peribadi. Untuk menggambarkan ejekan separa kaedah ini, kita perlu memberi contoh kelas dan memberitahu PowerMockito API untuk mengintipnya :

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 pengenalan kepada PowerMockito API, menunjukkan penggunaannya dalam menyelesaikan beberapa masalah yang dihadapi oleh pembangun ketika menggunakan kerangka Mockito.

Pelaksanaan contoh dan coretan kod ini terdapat dalam projek GitHub yang dipautkan.