Bagaimana cara mensimulasikan peristiwa yang menyebabkan pengecualian untuk menguji coba / tangkap blok?

14

Saya mengerti bagaimana pengecualian bekerja dan bagaimana menangkap dan menanganinya dalam C # tetapi bagaimana saya bisa mensimulasikan peristiwa yang dapat menyebabkan pengecualian untuk memastikan bahwa itu ditangkap dengan benar? Sebagai contoh, apakah mungkin untuk menjalankan aplikasi di semacam test bed di mana dimungkinkan untuk mensimulasikan masalah jaringan, masalah database, dll? Pengecualian berdasarkan sifatnya tampaknya sulit untuk direproduksi sehingga menyulitkan untuk memastikan kode Anda dapat mengatasinya.

Meskipun saya terutama mengembangkan menggunakan C # /. NET / Visual Studio, jawaban atau sumber daya yang berkaitan dengan bahasa lain dapat bermanfaat.

Piers Myers
sumber
Solusi lain yang mungkin dijelaskan dalam artikel MSDN ini: Pengujian Injeksi Kesalahan dengan TestApi
Giorgi

Jawaban:

13

1) Jika Anda mengikuti model injeksi ketergantungan, Anda dapat mengganti implementasi nyata dari bagian-bagian tertentu dengan tiruan yang akan melempar pengecualian saat Anda membutuhkannya. Namun itu akan mengharuskan Anda untuk awalnya merancang aplikasi Anda dengan cara tertentu atau benar-benar merekayasa ulang itu.

Suka:

public class SqlUsersRepository : IUsersRepository
{
    public void RegisterNewUser (User newUser)
    {
        throw new SqlException ("Connection timeout");
    }
}

Namun di sini kita akan memiliki masalah bahwa kode konsumen seharusnya tidak berkaitan dengan penanganan pengecualian implementasi konkret.

2) Pendekatan lain adalah mengganti panggilan metode tertentu dengan pembungkus khusus Anda.

Dari pada:

FileStream fs = File.OpenRead (path);

Kau gunakan:

FileStream fs = File.OpenRead_Test (path);

dengan memberikan metode ekstensi khusus (hanya ide cepat):

public static FileStream OpenRead_Test (this System.IO.File file, string path)
{
    throw new FileNotFoundException ();
}

sumber
3

Anda perlu melihat kerangka kerja mengejek.

Dengan ini Anda menggunakan injeksi ketergantungan untuk memanggil database palsu (katakanlah) daripada yang asli. Ini berarti Anda memiliki kendali penuh atas apa yang dikembalikan untuk setiap panggilan.

Anda kemudian mengatur tes yang ketika dipanggil hanya melempar pengecualian yang diinginkan:

public void Test1()
{
    throw new NullArgumentException();
}

Tes Anda lulus ketika kode Anda menangani ini dengan benar.

ChrisF
sumber
3

Mengejek dan menyuntikkan hanya bisa membuat Anda sejauh ini dan memerlukan perubahan besar dalam pendekatan dalam beberapa kasus.

Jika Anda tidak ingin mendesain ulang aplikasi agar sesuai dengan kerangka pengujian maka yang benar-benar Anda butuhkan adalah host atau lingkungan yang dicurangi karena kesalahan. Ada banyak cara untuk mensimulasikan keterlambatan jaringan pemadaman kami (bahkan alat uji Microsoft memiliki sedikit dari ini di area pengujian web). Saya telah berhasil dengan menempatkan mesin di belakang router yang dapat dirusak untuk mengubah simulasi dalam koordinasi dengan set database untuk menghasilkan kesalahan dan skrip untuk mengubah kesalahan yang dihasilkan database.

Bahkan dengan itu jika Anda pergi cukup cepat atau cukup jauh ke bawah ke perangkat keras ada kesalahan seperti masalah konkurensi dan kegagalan menulis tertunda yang cukup banyak Anda tidak dapat mensimulasikan. Kadang-kadang Anda harus membuatnya nyata dan di lain waktu Anda hanya perlu bekerja tanpa jaring pengaman.

Tagihan
sumber
Setuju - dalam beberapa kasus, Anda tidak dapat membayar biaya overhead dari injeksi dependensi dalam kode rilis Anda, misalnya. Bukan masalah sehari-hari, tetapi itu bisa terjadi.
Steve314