Saya memiliki beberapa pola berbeda yang saya gunakan. Saya menggunakan ExpectedException
atribut sebagian besar waktu ketika pengecualian diharapkan. Ini sudah cukup untuk kebanyakan kasus, namun, ada beberapa kasus ketika ini tidak cukup. Pengecualian mungkin tidak dapat ditangkap - karena dilemparkan oleh metode yang dipanggil oleh refleksi - atau mungkin saya hanya ingin memeriksa apakah kondisi lain berlaku, katakanlah transaksi dibatalkan atau beberapa nilai masih ditetapkan. Dalam kasus ini saya membungkusnya dalam try/catch
blok yang mengharapkan pengecualian yang tepat, Assert.Fail
apakah kode berhasil dan juga menangkap pengecualian umum untuk memastikan bahwa pengecualian yang berbeda tidak dilemparkan.
Kasus pertama:
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MethodTest()
{
var obj = new ClassRequiringNonNullParameter( null );
}
Kasus kedua:
[TestMethod]
public void MethodTest()
{
try
{
var obj = new ClassRequiringNonNullParameter( null );
Assert.Fail("An exception should have been thrown");
}
catch (ArgumentNullException ae)
{
Assert.AreEqual( "Parameter cannot be null or empty.", ae.Message );
}
catch (Exception e)
{
Assert.Fail(
string.Format( "Unexpected exception of type {0} caught: {1}",
e.GetType(), e.Message )
);
}
}
Assert.Throws
yang mencakup kedua kasus ini.Sekarang, 2017, Anda dapat melakukannya lebih mudah dengan Kerangka Kerja MSTest V2 yang baru :
sumber
System.Exception
dilempar. Yang lainnya, sepertiSystem.ArgumentException
akan gagal dalam ujian.Assert.ThrowsException<MyException>
akan hanya menguji jenis pengecualian yang disediakan, dan bukan jenis pengecualian turunannya. Dalam contoh saya, jika diujiSub
adalah untukThrow
sebuahMyInheritedException
(tipe turunan dari kelas dasarMyException
), maka tes akan gagal .Try { SubToTest(); Assert.Fail("...") } Catch (AssertFailedException e) {throw;} Catch (MyException e) {...}
. Perhatikan yang paling penting dariCatch (AssertFailedException e) {throw;}
(lih. Komentar dari allgeek)Saya baru di sini dan tidak memiliki reputasi untuk berkomentar atau memberi suara negatif, tetapi ingin menunjukkan kesalahan dalam contoh dalam balasan Andy White :
Di semua kerangka kerja pengujian unit yang saya kenal,
Assert.Fail
bekerja dengan memberikan pengecualian, sehingga tangkapan umum sebenarnya akan menutupi kegagalan pengujian. JikaSomethingThatCausesAnException()
tidak melempar,Assert.Fail
kemauan, tapi itu tidak akan pernah meluncur ke runner pengujian untuk menunjukkan kegagalan.Jika Anda perlu menangkap pengecualian yang diharapkan (yaitu, untuk menegaskan detail tertentu, seperti pesan / properti pada pengecualian), penting untuk menangkap tipe khusus yang diharapkan, dan bukan kelas Exception dasar. Itu akan memungkinkan
Assert.Fail
pengecualian untuk diluncurkan (dengan asumsi Anda tidak melemparkan jenis pengecualian yang sama dengan yang dilakukan oleh kerangka pengujian unit Anda), tetapi masih memungkinkan validasi pada pengecualian yang dilemparkan olehSomethingThatCausesAnException()
metode Anda .sumber
Mulai v 2.5, NUnit memiliki tingkat metode berikut
Assert
untuk menguji pengecualian:Assert.Throws , yang akan menguji jenis pengecualian yang tepat:
Dan
Assert.Catch
, yang akan menguji pengecualian dari tipe tertentu, atau tipe pengecualian yang diturunkan dari tipe ini:Selain itu, saat men-debug pengujian unit yang menampilkan pengecualian, Anda mungkin ingin mencegah VS melanggar pengecualian .
Edit
Hanya untuk memberikan contoh komentar Matthew di bawah ini, kembalinya generik
Assert.Throws
danAssert.Catch
merupakan pengecualian dengan jenis pengecualian, yang kemudian dapat Anda periksa untuk pemeriksaan lebih lanjut:sumber
Assert.Throws
, selain itu ia mengembalikan pengecualian sehingga Anda dapat menulis pernyataan lebih lanjut tentang pengecualian itu sendiri.Sayangnya MSTest MASIH hanya benar-benar memiliki atribut ExpectedException (hanya menunjukkan seberapa besar MS peduli tentang MSTest) yang IMO cukup buruk karena merusak pola Atur / Tindakan / Tegaskan dan tidak memungkinkan Anda untuk menentukan dengan tepat baris kode mana yang Anda harapkan pengecualiannya terjadi.
Ketika saya menggunakan (/ dipaksa oleh klien) untuk menggunakan MSTest, saya selalu menggunakan kelas helper ini:
Contoh penggunaan:
sumber
Sebagai alternatif untuk menggunakan
ExpectedException
atribut, terkadang saya mendefinisikan dua metode yang berguna untuk kelas pengujian saya:AssertThrowsException()
mengambil sebuah delegasi dan menegaskan bahwa itu melempar pengecualian yang diharapkan dengan pesan yang diharapkan.AssertDoesNotThrowException()
mengambil delegasi yang sama dan menegaskan bahwa itu tidak memunculkan pengecualian.Penyandingan ini bisa sangat berguna ketika Anda ingin menguji bahwa pengecualian dilemparkan dalam satu kasus, tetapi tidak di kasus lainnya.
Menggunakannya, kode pengujian unit saya mungkin terlihat seperti ini:
Bagus dan rapi ya?
Metode
AssertThrowsException()
dan sayaAssertDoesNotThrowException()
didefinisikan pada kelas dasar umum sebagai berikut:sumber
Dengan sebagian besar framework pengujian unit .net, Anda dapat menempatkan atribut [ExpectedException] pada metode pengujian. Namun ini tidak dapat memberi tahu Anda bahwa pengecualian terjadi pada titik yang Anda harapkan. Di situlah xunit.net dapat membantu.
Dengan xunit Anda memiliki Assert.Throws, sehingga Anda dapat melakukan hal-hal seperti ini:
[Fakta] adalah xunit yang setara dengan [TestMethod]
sumber
Tandai pengujian dengan ExpectedExceptionAttribute (ini adalah istilah di NUnit atau MSTest; pengguna framework pengujian unit lain mungkin perlu menerjemahkan).
sumber
Sarankan menggunakan sintaks delegasi bersih NUnit .
Contoh untuk pengujian
ArgumentNullExeption
:sumber