NUnit Assert.Throws yöntemi veya ExpectedException özniteliği kullanılsın mı?


149

Bunların istisnaları test etmenin iki ana yolu olduğunu keşfettim:

Assert.Throws<Exception>(()=>MethodThatThrows());

[ExpectedException(typeof(Exception))]

Bunlardan hangisi en iyisidir? Biri diğerine göre avantaj sağlıyor mu? Yoksa sadece kişisel bir tercih meselesi mi?


3
Üçüncü seçenek akıcı stildir:Assert.That(() => MethodThatThrows(), Throws.Exception)
Jack Ukleja

1
NUnit sürüm 3 ve sonraki sürümler artık ExpectedExceptionözniteliği desteklemediğinden, sürüm 3+ için yalnızca Assert.Throwsvaryant ilgilidir.
joanlofe

Neden böyle? Nunit3 bu desteği bırakmaya mı karar verdi? Google'da dolaşıyordu ve bunun için bir açıklama bulamadı ... JUnit hala bu yolu destekliyor, değil mi?
ahaaman

Yanıtlar:


92

İlki, birden fazla arama ile birden fazla istisnayı test etmenize olanak tanır:

Assert.Throws(()=>MethodThatThrows());
Assert.Throws(()=>Method2ThatThrows());

İkincisi, test işlevi başına yalnızca bir istisna test etmenize izin verir.


26
Bir test yalnızca bir ayrı mantık parçasını test etmelidir, bu nedenle aynı birim testinde iki hatayı test etmek kötü bir uygulama olarak değerlendirilmez mi?
SamuelDavis

5
@SamuelDavis - genel olarak aynı testte farklı vakaları test etmek istemezsiniz. Bununla birlikte, çoklu için bazı kullanım durumları olabilir Assert.Throws.
chue x

3
Her iki durumda da, burada istisnayı bir parametre olarak alırsınız, bu da istisnadaki ayrıntıları belirtmenize izin verir. Ayrıca, "Beklenen istisna" nın kullanılması, sizi başka bir yöntem çağrısında atılan aynı istisna türünden korumaz. Burada, tüm testi değil, kesin yöntemi hedeflersiniz. Testinizin çok az kod gerektirmesine rağmen, asla güvende değilsiniz. Özellikle kod karmaşık hale geldiğinde ve / veya istisna çok genel hale geldiğinde. "ArgumentNullExceptions" gibi şeyler çok fazla fırlatılabilir ve örneğin ExpectedException kullanılarak kolayca gözden kaçabilir. Assert.Throws bunu kaçırmaz.
Gil Sand

256

Temel fark şudur:

ExpectedException()öznitelik , test yönteminin herhangi bir yerinde istisna meydana gelirse testi geçmesini sağlar .
Kullanımı, istisnanın beklendiği yerde kodun yerini Assert.Throws()belirlemeye izin verir exact.

NUnit 3.0, resmi desteği ExpectedExceptiontamamen bırakıyor .

Bu yüzden kesinlikle öznitelikten Assert.Throws()ziyade yöntemi kullanmayı tercih ediyorum ExpectedException().


8
Bu açık ara doğru cevap. Bu arada, Assert.Throws (), sizin için önemliyse, istisnanın özelliklerinin ek olarak incelenmesine izin verebilen istisnayı da döndürür.
mükemmeliyetçi

1
Son olarak, ExpectedException'ı neden çalışmak için alamadığımı yanıtlayın .. 3. sürümle
Ocak

2
İşte bağlantı github.com/nunit/docs/wiki/Breaking-Changes - ExpectedExceptionAttribute artık desteklenmiyor.
Anton Lyhin

Bunu NUnit 3.0 altında çalışacak şekilde değiştirmek için şu şekilde
Andrei Krasutski

39

İstisna atıldıktan sonra diğer koşulları doğrulamama ve ileri sürmeme izin verdiği için assert.throws'u tercih ediyorum.

    [Test]
    [Category("Slow")]
    public void IsValidLogFileName_nullFileName_ThrowsExcpetion()
    {
        var a = new MyTestObject();

        // the exception we expect thrown from the IsValidFileName method
        var ex = Assert.Throws<ArgumentNullException>(() => a.IsValidLogFileName(""));

        // now we can test the exception itself
        Assert.That(ex.Message == "Blah");

    }

Bu daha iyi cevaplardan biridir, istisna atıldıktan sonra bir şeyin hatalı bir duruma girdiğini doğrulamak istemeniz oldukça yaygındır.
Rhys Bevilaqua

İyi cevap! Ama anlamı nedir [Category("Slow")]ve a?
themefield

Testlerinizi gruplamak için Kategoriler'i kullanabilirsiniz - bu örnek için gerekli değildir - bu durumda "Yavaş", her seferinde veya sadece gece veya haftalık olarak "yavaş" testler çalıştırıp çalıştırmamayı seçebilmek isteyebileceğiniz anlamına gelebilir çalışır veya bir şey. "A" nın teknik olarak bir sözdizimi hatası olduğuna inanıyorum, ama bu sadece test ettiğiniz nesne.
Mike Parkhill

11

Ayrıca beklediğiniz hatayı güçlü bir şekilde yazabilirsiniz (eski özellik sürümü gibi).

Assert.Throws<System.InvalidOperationException>(() => breakingAction())

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.