Bagaimana cara saya menggunakan
Assert
(atau kelas Tes lainnya?) Untuk memverifikasi bahwa pengecualian telah dilemparkan?
830
Bagaimana cara saya menggunakan
Assert
(atau kelas Tes lainnya?) Untuk memverifikasi bahwa pengecualian telah dilemparkan?
Jawaban:
Untuk "Tes Tim Visual Studio" tampaknya Anda menerapkan atribut ExpectedException ke metode pengujian.
Contoh dari dokumentasi di sini: Panduan Pengujian Unit dengan Tes Tim Visual Studio
sumber
Biasanya kerangka pengujian Anda akan memiliki jawaban untuk ini. Tetapi jika itu tidak cukup fleksibel, Anda selalu dapat melakukan ini:
Seperti yang ditunjukkan oleh @Jonas, ini TIDAK berfungsi untuk menangkap basis Pengecualian:
Jika Anda benar-benar harus menangkap Pengecualian, Anda harus memikirkan kembali Assert.Fail (). Tapi sungguh, ini pertanda kamu tidak boleh menulis ini dengan tangan; periksa kerangka pengujian Anda untuk opsi, atau lihat apakah Anda dapat melemparkan pengecualian yang lebih bermakna untuk diuji.
Anda harus dapat menyesuaikan pendekatan ini dengan apa pun yang Anda suka - termasuk menentukan jenis pengecualian apa yang harus ditangkap. Jika Anda hanya mengharapkan tipe tertentu, selesaikan
catch
blok dengan:sumber
Metode pilihan saya untuk mengimplementasikan ini adalah menulis metode yang disebut Throws, dan menggunakannya sama seperti metode Assert lainnya. Sayangnya, .NET tidak memungkinkan Anda untuk menulis metode ekstensi statis, jadi Anda tidak dapat menggunakan metode ini seolah-olah itu milik build di kelas Assert; buat saja yang disebut MyAssert atau yang serupa. Kelasnya terlihat seperti ini:
Itu berarti unit test Anda terlihat seperti ini:
Yang terlihat dan berperilaku jauh lebih seperti sintaks tes unit Anda.
sumber
Assert.ThrowsException<T>
danAssert.ThrowsExceptionAsync<T>
- melihat blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/...jika Anda menggunakan NUNIT, Anda dapat melakukan sesuatu seperti ini:
Dimungkinkan juga untuk menyimpan pengecualian yang dilemparkan untuk memvalidasi lebih lanjut:
Lihat: http://nunit.org/docs/2.5/exceptionAsserts.html
sumber
Jika Anda menggunakan MSTest, yang awalnya tidak memiliki
ExpectedException
atribut, Anda bisa melakukan ini:sumber
Berhati-hatilah dalam menggunakan ExpectedException, karena dapat menyebabkan beberapa perangkap seperti yang ditunjukkan di sini:
http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx
Dan di sini:
http://xunit.github.io/docs/comparisons.html
Jika Anda perlu menguji pengecualian, ada beberapa cara yang tidak disukai. Anda dapat menggunakan metode coba {act / fail} catch {assert}, yang dapat berguna untuk kerangka kerja yang tidak memiliki dukungan langsung untuk tes pengecualian selain ExpectedException.
Alternatif yang lebih baik adalah dengan menggunakan xUnit.NET, yang merupakan kerangka pengujian unit yang sangat modern, berwawasan ke depan, dan dapat diperluas yang telah belajar dari semua kesalahan yang lain, dan ditingkatkan. Salah satu peningkatan tersebut adalah Assert.Throws, yang menyediakan sintaks yang jauh lebih baik untuk menyatakan pengecualian.
Anda dapat menemukan xUnit.NET di github: http://xunit.github.io/
sumber
MSTest (v2) sekarang memiliki fungsi Assert.ThrowsException yang dapat digunakan seperti ini:
Anda dapat menginstalnya dengan nuget:
Install-Package MSTest.TestFramework
sumber
Dalam proyek saya sedang mengerjakan kami punya solusi lain melakukan ini.
Pertama, saya tidak suka ExpectedExceptionAttribute karena tidak mempertimbangkan metode panggilan mana yang menyebabkan Exception.
Saya melakukan ini dengan metode helpermet sebagai gantinya.
Uji
Metode Helper
Rapi, bukan;)
sumber
Ini adalah atribut pada metode pengujian ... Anda tidak menggunakan Assert. Terlihat seperti ini:
sumber
Anda dapat mengunduh paket dari Nuget menggunakan: PM> Instal-Paket MSTestExtensions yang menambahkan Assert.Throws () sintaks dalam gaya nUnit / xUnit ke MsTest.
Instruksi tingkat tinggi: unduh perakitan dan mewarisi dari BaseTest dan Anda dapat menggunakan Assert.Throws () sintaks .
Metode utama untuk implementasi Throws terlihat sebagai berikut:
Pengungkapan: Saya mengumpulkan paket ini.
Info Lebih Lanjut: http://www.bradoncode.com/blog/2012/01/asserting-exceptions-in-mstest-with.html
sumber
Anda dapat mencapai ini dengan satu garis sederhana.
Jika operasi Anda
foo.bar()
async:Jika
foo.bar()
tidak asyncsumber
ArgumentException
misalnya. Try Catch yang lama dan uji respon pengecualian masih lebih disukai jika Anda memiliki kriteria canggih untuk diuji, tetapi untuk banyak kasus saya, ini sangat membantu!Saya tidak merekomendasikan menggunakan atribut ExpectedException (karena terlalu membatasi dan rawan kesalahan) atau untuk menulis blok try / catch di setiap tes (karena terlalu rumit dan rawan kesalahan). Gunakan metode penegasan yang dirancang dengan baik - baik yang disediakan oleh kerangka pengujian Anda atau tulis sendiri. Inilah yang saya tulis dan gunakan.
Contoh menggunakan:
CATATAN
Mengembalikan pengecualian alih-alih mendukung validasi panggilan balik adalah ide yang masuk akal kecuali bahwa melakukan hal itu membuat sintaks panggilan pernyataan ini sangat berbeda dari pernyataan lain yang saya gunakan.
Tidak seperti yang lain, saya menggunakan 'propagasi' bukan 'melempar' karena kami hanya dapat menguji apakah pengecualian merambat dari panggilan. Kami tidak dapat menguji secara langsung bahwa pengecualian dilemparkan. Tapi saya kira Anda bisa membayangkan melempar artinya: dibuang dan tidak tertangkap.
PIKIRAN FINAL
Sebelum beralih ke pendekatan semacam ini, saya mempertimbangkan untuk menggunakan atribut ExpectedException ketika tes hanya memverifikasi tipe pengecualian dan menggunakan blok coba / tangkap jika diperlukan lebih banyak validasi. Tetapi, saya tidak hanya harus memikirkan teknik mana yang akan digunakan untuk setiap tes, tetapi mengubah kode dari satu teknik ke teknik lainnya karena kebutuhan berubah bukanlah usaha yang sepele. Menggunakan satu pendekatan yang konsisten menghemat upaya mental.
Jadi secara ringkas, pendekatan ini olahraga: kemudahan penggunaan, fleksibilitas dan ketahanan (sulit untuk melakukannya salah).
sumber
Helper yang disediakan oleh @Richiban di atas berfungsi dengan baik kecuali itu tidak menangani situasi di mana pengecualian dilemparkan, tetapi bukan tipe yang diharapkan. Berikut alamat yang:
sumber
Karena Anda menyebutkan menggunakan kelas tes lain, opsi yang lebih baik daripada
ExpectedException
atribut adalah menggunakan Shoudly 's Should.Throw .Katakanlah kita memiliki persyaratan bahwa pelanggan harus memiliki alamat untuk membuat pesanan . Jika tidak,
CreateOrderForCustomer
metode harus menghasilkanArgumentException
. Lalu kita bisa menulis:Ini lebih baik daripada menggunakan
ExpectedException
atribut karena kita lebih spesifik tentang apa yang harus membuang kesalahan. Ini membuat persyaratan dalam tes kami lebih jelas dan juga membuat diagnosis lebih mudah ketika tes gagal.Catatan ada juga
Should.ThrowAsync
untuk pengujian metode asinkron.sumber
Sebagai alternatif, Anda dapat mencoba menguji pengecualian yang sebenarnya dilemparkan dengan 2 baris berikutnya dalam pengujian Anda.
sumber
Dalam pengujian unit bawaan VS jika Anda hanya ingin memverifikasi bahwa "pengecualian" dilemparkan, tetapi Anda tidak tahu jenisnya, Anda dapat menggunakan tangkapan semua:
sumber
Yah saya akan cukup meringkas apa yang orang lain katakan di sini sebelumnya ... Ngomong-ngomong, ini kode yang saya buat sesuai dengan jawaban yang baik :) Yang tersisa hanyalah menyalin dan menggunakan ...
sumber
Lihat nUnit Documents untuk contoh tentang:
sumber
Ini akan tergantung pada kerangka tes apa yang Anda gunakan?
Di MbUnit, misalnya, Anda bisa menentukan pengecualian yang diharapkan dengan atribut untuk memastikan bahwa Anda mendapatkan pengecualian yang benar-benar Anda harapkan.
sumber
Jika menggunakan NUnit , coba ini:
sumber
Ada perpustakaan luar biasa bernama NFluent yang mempercepat dan memudahkan cara Anda menulis pernyataan .
Cukup mudah untuk menulis pernyataan untuk melemparkan pengecualian:
sumber
Meskipun ini adalah pertanyaan lama, saya ingin menambahkan pemikiran baru ke dalam diskusi. Saya telah memperpanjang Arrange, Act, Assert pattern menjadi Expected, Arrange, Act, Assert. Anda dapat membuat pointer pengecualian yang diharapkan, lalu menegaskan itu ditugaskan. Ini terasa lebih bersih daripada melakukan Asserts Anda di blok tangkap, meninggalkan bagian Act Anda sebagian besar hanya untuk satu baris kode untuk memanggil metode yang sedang diuji. Anda juga tidak perlu
Assert.Fail();
ataureturn
dari banyak titik dalam kode. Pengecualian lain yang dilemparkan akan menyebabkan tes gagal, karena itu tidak akan tertangkap, dan jika pengecualian dari tipe yang Anda harapkan dilemparkan, tetapi itu bukan yang Anda harapkan, Menegaskan terhadap pesan atau properti lain dari pengecualian membantu memastikan tes Anda tidak akan lulus secara tidak sengaja.sumber