JUnit Tes Pengecualian yang Diharapkan: @Test(diharapkan)

⚡ Ringkasan Cerdas

JUnit Pengujian pengecualian memastikan bahwa suatu metode melempar kesalahan yang seharusnya dilempar, menggunakan parameter opsional yang diharapkan dari anotasi @Test. JUnit 4 dan metode assertThrows di JUnit 5.

  • 🔘 Tujuan: Buktikan bahwa input yang tidak valid menghasilkan pengecualian yang didokumentasikan, bukan jawaban salah yang tidak menimbulkan pesan kesalahan.
  • ☑️ sintaks: @Test(expected = ArithmeticException.class) hanya berhasil jika tipe pengecualian yang tepat tersebut dilemparkan.
  • Contoh: JUnitPesan tersebut dibagi dengan nol, dan AirthematicTest mengharapkan ArithmeticException sebagai hasilnya.
  • 🧪 Alternatif: Blok try yang diikuti dengan fail() memungkinkan Anda untuk memeriksa pengecualian yang ditangkap sebelum membuat pernyataan (assertion) terhadapnya.
  • JUnit 5: assertThrows mengembalikan pengecualian yang ditangkap, sehingga pesan dan penyebabnya juga dapat dipastikan.
  • 📌 Batu sandungan: Parameter yang diharapkan diteruskan ke mana pun pengecualian terjadi, yang dapat menyembunyikan kegagalan dalam kode pengaturan.

JUnit Pengujian pengecualian yang diharapkan menggunakan parameter @Test(expected)

JUnit menyediakan fasilitas untuk tracuntuk mendeteksi pengecualian dan juga untuk memeriksa apakah kode tersebut menghasilkan pengecualian yang diharapkan atau tidak.

JUnit 4 menyediakan cara yang mudah dan mudah dibaca untuk pengujian pengecualian. Anda dapat menggunakan:

  • Parameter opsional (yang diharapkan) dari Anotasi @Test, dan
  • Untuk tracJika informasi tersebut ada, maka “fail()” dapat digunakan.

Sementara pengujian Jika terjadi pengecualian, Anda perlu memastikan bahwa kelas pengecualian yang Anda berikan dalam parameter opsional tersebut Anotasi @Test Ini adalah pengecualian yang sama yang sebenarnya dilemparkan oleh metode tersebut. Hal ini karena Anda mengharapkan pengecualian dari metode yang sedang Anda jalankan. pengujian unit; jika tidak, milik kita JUnit tes akan gagal.

Contoh: @Test(expected = IllegalArgumentException.class)

Dengan menggunakan parameter “expected”, Anda dapat menentukan nama pengecualian yang mungkin dilemparkan oleh pengujian kita. Dalam contoh di atas, Anda menggunakan “Pengecualian Argumen Ilegal“, yang akan dilemparkan oleh pengujian jika pengembang menggunakan argumen yang tidak diizinkan.

Contoh penggunaan @Test(expected)

Mari kita pahami pengujian pengecualian dengan membuat sebuah Java kelas dengan metode yang melempar pengecualian. pengecualianAnda akan menanganinya dan mengujinya di kelas pengujian. Pertimbangkan JUnitFile Message.java memiliki sebuah metode yang melakukan operasi matematika. Pembagian pada baris 14 membagi dengan nol, sehingga metode tersebut selalu melempar "ArithmeticException". Lihat di bawah ini:

JUnitKelas pesan di Eclipse dengan printMessage dibagi dengan nol pada baris 14

package guru99.junit;

public class JUnitMessage{

	private String message;

	public JUnitMessage(String message) {
		this.message = message;
	}

public void printMessage(){

	System.out.println(message); 
	int divide=1/0;

}

public String printHiMessage(){ 

	message="Hi!" + message;
	
	System.out.println(message);

	return message;
}

}

Code Penjelasan:

  • Code Baris 7: Membuat konstruktor berparameter dengan inisialisasi bidang.
  • Code Baris 11-14: Membuat metode untuk operasi matematika.
  • Code Baris 18: Membuat metode lain untuk mencetak pesan.
  • Code Baris 20: Membuat string baru untuk mencetak pesan.
  • Code Baris 22: Mencetak pesan baru yang dibuat pada baris 20.

Mari kita buat kelas pengujian untuk hal di atas. Java kelas untuk memverifikasi pengecualian.

Lihat di bawah ini kelas pengujian yang melakukan pengujian unit terhadap pengecualian (ArithmeticException di sini) yang dilemparkan dari atas. Java kelas:

AirthematicTest.java

Tangkapan layar di bawah ini menunjukkan pengujian yang sama di editor, di mana file disimpan sebagai AirthematicTest1, dengan parameter yang diharapkan disorot pada baris 13:

Kelas AirthematicTest1 di Eclipse dengan @Test(expected = ArithmeticException.class) disorot pada baris 13

package guru99.junit;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class AirthematicTest {

	public String message = "Saurabh";
	
	JUnitMessage junitMessage = new JUnitMessage(message);
	
	@Test(expected = ArithmeticException.class)
	public void testJUnitMessage(){

		System.out.println("Junit Message is printing ");
		junitMessage.printMessage();

	}

	@Test
	public void testJUnitHiMessage(){ 
		message="Hi!" + message;
		System.out.println("Junit Message is printing ");
		assertEquals(message, junitMessage.printHiMessage());
	
	}
}

Code Penjelasan:

  • Code Baris 13: Gunakan anotasi @Test untuk membuat pengujian kita. Saat Anda menjalankan metode dari kelas di atas, metode tersebut akan memanggil operasi matematika. Di sini, ArithmeticException diharapkan terjadi, jadi Anda mencantumkannya sebagai parameter dalam @Test.
  • Code Baris 17: Memanggil printMessage() dari JUnitPesan.java.
  • Code Baris 21-22: Membuat metode pengujian lain untuk memeriksa pesan "Hi", kali ini tanpa parameter yang diharapkan.

Kelas ini memiliki dua metode pengujian, sehingga satu kali eksekusi akan menjalankan keduanya: metode yang mengharapkan ArithmeticException dan metode yang melakukan penegasan pada string yang dikembalikan.

Catatan: Contoh ini muncul dengan tiga nama berbeda dalam materi aslinya — daftar tersebut menyebut kelasnya AirthematicTest, tangkapan layar editor menunjukkan AirthematicTest1, dan tampilan hasil melaporkan JunitTestExample. Kode di setiap tampilan identik; hanya nama filenya yang berbeda.

Mari kita jalankan dan verifikasi hasilnya. JUnit lihat di bawah laporan jalannya JunitTestExample.java.

Keluaran:

Berikut adalah hasilnya, yang menunjukkan pengujian berhasil tanpa kegagalan. tracseperti yang diberikan di bawah ini:

Eclipse JUnit Lihat laporan: Berjalan 2/2 tanpa kesalahan dan tanpa kegagalan untuk JunitTestExample

Kedua metode tersebut berhasil. Metode pertama berhasil karena ArithmeticException yang dideklarasikan memang terjadi, dan metode kedua berhasil karena string yang dikembalikan cocok. Seandainya pembagian tersebut tidak pernah menghasilkan pengecualian, JUnit Metode pertama akan gagal dengan pesan “Expected exception: java.lang.ArithmeticException”.

Tiga Cara untuk Menguji Pengecualian di JUnit 4

Parameter yang diharapkan adalah yang terpendek dari ketiganya. JUnit Ada 4 idiom, tetapi tidak selalu yang tepat. Tabel tersebut membandingkannya berdasarkan dua pertanyaan yang menentukan pilihan: dapatkah Anda menegaskan pesan tersebut, dan apakah Anda tahu baris mana yang tepat?

Pendekatan Menegaskan pesan tersebut? Apakah itu menjepit garis lempar? Terbaik untuk
@Test(expected = X.class) Tidak Tidak — baris mana pun dalam metode tersebut dapat menimbulkan kesalahan. Tes singkat di mana hanya tipe pengecualian yang penting.
coba / gagal() / tangkap Ya, di dalam blok tangkap Ya — hanya panggilan yang dijaga ketat yang dipantau. Tes yang harus memeriksa pesan atau penyebabnya.
@Aturan ExpectedException Ya, melalui expectMessage(). Tidak Sistem lama yang sudah dibangun berdasarkan aturan.

Idiom `fail()` yang disebutkan dalam pengantar terlihat seperti ini. Jika panggilan tidak melempar pengecualian, `fail()` akan dijalankan dan pengujian akan melaporkan pesan yang Anda tulis:

@Test
public void testDivideByZero() {
    try {
        junitMessage.printMessage();
        fail("Expected an ArithmeticException");
    } catch (ArithmeticException e) {
        assertEquals("/ by zero", e.getMessage());
    }
}

Aturan ExpectedException berada di antara keduanya. Aturan ini sudah usang sejak JUnit 4.13 mendukung metode assertThrows yang dijelaskan selanjutnya, jadi yang baru JUnit 4 tes seharusnya tidak mengadopsinya.

Cara Menguji Pengecualian di JUnit 5 dengan assertThrows()

JUnit 5 menghapus parameter yang diharapkan dari @Test sepenuhnya. Jupiter menyediakan assertThrows(), yang menerima kelas pengecualian dan lambda yang berisi kode yang sedang diuji. Ia mengembalikan pengecualian yang ditangkapnya, sehingga pesan, penyebab, dan bidang kustom apa pun dapat ditegaskan setelahnya.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;

public class AirthematicJupiterTest {

    JUnitMessage junitMessage = new JUnitMessage("Saurabh");

    @Test
    public void testJUnitMessage() {
        ArithmeticException thrown = assertThrows(
                ArithmeticException.class,
                () -> junitMessage.printMessage());
        assertEquals("/ by zero", thrown.getMessage());
    }
}

Tiga hal yang terkait pernyataan Melengkapi keluarga:

  • assertThrows menerima tipe pengecualian atau subkelas apa pun darinya.
  • assertThrowsExactly menolak subkelas, jadi hanya tipe yang disebutkan namanya yang lolos.
  • assertDoesNotThrow menyatakan harapan yang berlawanan, yaitu bahwa blok tersebut selesai dengan bersih.

The JUnit Kode 4 di halaman ini masih berjalan di JUnit Platform ini menggunakan mesin lama, jadi tidak ada yang perlu ditulis ulang agar tetap berfungsi saat proyek bermigrasi.

Kesalahan Umum Saat Menguji Pengecualian di JUnit

Pengujian pengecualian gagal dalam sejumlah kecil cara yang mudah dikenali. Setiap baris menyebutkan gejala, penyebab, dan solusinya.

Gejala Menyebabkan Memperbaiki
Pengecualian yang diharapkan: java.lang.ArithmeticException Metode ini diselesaikan tanpa melempar. Periksa apakah input benar-benar tidak valid, lalu jalankan kembali.
Tesnya berhasil, tetapi baris yang salah dimasukkan. Parameter yang diharapkan memantau keseluruhan metode, termasuk pengaturan. Pindahkan setup ke luar, atau ganti dengan assertThrows di sekitar satu panggilan.
Tipe pengecualian yang tidak ditangani di editor Pengecualian yang diperiksa dilemparkan tetapi tidak pernah dideklarasikan. Tambahkan pengecualian pada tanda tangan metode pengujian.
Pengujian berhasil pada subkelas yang tidak Anda inginkan. assertThrows menerima subkelas dari tipe yang disebutkan. Gunakan assertThrowsExactly untuk pencocokan tipe yang ketat.
"expected" bukanlah atribut yang valid. Tes tersebut dikompilasi terhadap anotasi Jupiter @Test. Impor org.junit.Test untuk JUnit 4, atau pindah ke assertThrows.

Baris terakhir adalah baris yang paling sering membingungkan orang di tengah proses migrasi, karena kedua anotasi tersebut diberi nama @Test dan hanya impor yang membedakannya. Keeping satu JUnit versi per Kasus cobaan kelas tersebut menghindari seluruh kelas masalah.

Pertanyaan Umum Demo Slot

Parameter yang diharapkan tidak dapat memeriksa pesan. Bungkus panggilan tersebut dalam blok try, panggil fail() segera setelahnya, dan lakukan assert pada getMessage() di dalam blok catch. JUnit Nomor 5 membuat ini lebih sederhana karena assertThrows mengembalikan pengecualian yang ditangkap.

JUnit Tes gagal dan melaporkan "Expected exception" diikuti oleh kelas yang Anda sebutkan. Tidak ada hal lain yang dilaporkan, sehingga tes yang tidak pernah melempar exception terlihat identik dengan tes yang kode produksinya diam-diam mengubah perilakunya.

Asisten AI membaca sebuah metode, mencantumkan input yang mencapai setiap pernyataan throw, dan menyusun sebuah pengujian untuk setiap cabang. Perlakukan output sebagai titik awal: asisten menyimpulkan tipe pengecualian dari kode, sehingga throw yang salah disalin dengan tepat ke dalam pengujian.

Copilot Mengikuti gaya apa pun yang sudah ada di dalam file, jadi proyek campuran akan mendapatkan campuran. Periksa baris impor sebelum menerima saran, karena org.junit.Test dan org.junit.jupiter.api.Test terlihat identik di editor.

Itu masih ada, tetapi sudah tidak digunakan lagi. JUnit 4.13 dan tidak pernah diporting ke Jupiter. Rangkaian pengujian yang ada dapat tetap menggunakannya; pengujian baru sebaiknya menggunakan assertThrows, yang lebih mudah dibaca dan tidak memerlukan bidang aturan publik.

Ya. Parameter lambda adalah Executable, yang dideklarasikan untuk melempar Throwable, jadi pengecualian yang diperiksa tidak memerlukan klausa throws pada metode pengujian itu sendiri. Hal yang sama berlaku untuk JUnit 4. Ungkapan "coba dan tangkap".

assertThrows menerima subkelas apa pun dari tipe yang Anda sebutkan, jadi mengharapkan RuntimeException juga akan meneruskan NullPointerException. Gunakan assertThrowsExactly ketika kelas yang tepat penting, atau sebutkan tipe paling spesifik yang sebenarnya Anda harapkan.

Hanya jika pengecualian tersebut merupakan bagian dari ketentuan tersebut.tract. Menguji pengecualian, metode ini tidak pernah menjanjikan untuk melempar kunci dalam perilaku yang tidak disengaja dan membuat refactoring lebih sulit, yang mengalahkan tujuan pengujian.

Ringkaslah postingan ini dengan: