2013-07-25 25 views
5

Bir hizmet için bazı test otomasyonu üzerinde çalışıyorum ve bir "oturum" sınıfına genel kurulum & doğrulamasının düzgün bir yolunu buldum. Ben vb rolü başına doğru kimlik doğrulaması ile test ediyorum servisiyle bağlantı kurmak Oturum nesne YapıcıdaHerhangi bir istisnanın atılmış olup olmadığını nasıl kontrol edebilirim?

using (var managerSession = new Session(managerRole)) 
{ 
    // A manager puts some items in warehouse 
} 

using (var employeeSession = new Session(employeeRole)) 
{ 
    // An employee moves items from warehouse to store 
} 

using (var customerSession = new Session(customerRole)) 
{ 
    // A customer can buy items from the store 
} 

ve oturum imhası içinde:

Kavramsal olarak, bir test durumu şöyle görünebilir() yöntemi Ortak bir doğrulama bloğum var, örneğin, oturum ömrü boyunca sunucu tarafı hataları veya uyarılarının yükseltilmediğini denetler.

Şimdi, elbette, bu bir çeşit örüntüyü kötüye kullanmaktır ve eğer bir test blokları içindeki test kodu bir istisna atarsa ​​ve doğrulama bloğu da bir istisna atarsa, ikinci istisna ilkini maskeleyecektir. Bu senaryo varsa

Kavramsal olarak,:

using (var managerSession = new Session(managerRole)) 
{ 
    Assert.IsTrue(managerSession.DoJob(), "Manager did not do his job"); 
} 

... ve assert başarısız veya managerSession.DoJob() çağrısı bir istisna atar, sonra ben için Oturum Dispose() yöntemini istiyorum doğrulama bloğu atlamak, yani test yöntemi asla aslında

'işini yapmadı Yöneticisi' ile başarısız olursa 'Hizmet bağlantı hatalar var' ile başarısız şekilde

public void Dispose() 
{ 
    if (NoExceptionThrown()) 
    { 
     Assert.IsFalse(this.serviceConnection.HasErrors(), "Service connection has errors"); 
    } 

    this.serviceConnection.Dispose(); 
} 

...Sorum şu: 'NoExceptionThrown()' yöntemini uygulamak mümkün mü? Kullanılabilen ThreadCurrentThread'de kontrol edilebilen bazı gizli özellikler var mı?

Güncelleme:

Sorum şu değil

Tabii onun yerine bu desen kullanabilirsiniz bu :-) refactor nasıl: (

Session.ForRole(managerRole, (session) => { /* Test code here */ }); 

statik yöntemle ForRole ile)

public static void ForRole(Role r, Action<Session> code) 
{ 
    var session = new Session(r); 
    try 
    { 
     code(session); 
     Assert.IsFalse(session.serviceConnection.HasErrors()); 
    } 
    finally 
    { 
     session.Dispose(); 
    } 
} 

Ancak, yukarıda tarif edildiği gibi istisna durumunu ele geçirmenin bir yolunun olup olmadığını merak ediyorum.

+2

İki şey. Birincisi, evet, bu 'IDisposable' kötüye. "Mümkün olan en kısa sürede serbest bırakılması gereken yönetilmeyen bir kaynağa sahibim" anlamına gelen "IDisposable" ifadesini kullanın. Başka bir şey yapmak, kodunuzun okunmasını zorlaştırır. İkincisi, herhangi bir * istisna ya da sadece * yakalanmamış * istisnalar hakkında endişe duyuyor musunuz? Test kodunun bir istisna attığını, yakaladığını ve normal şekilde tamamlandığını varsayalım. İşaretlenmeli mi? –

+0

Ah, sadece _uncaught_ istisnaları hakkında endişeliyim. Sorunu güncelleyeceğim ... – Christoffer

+0

Kimlik hırsızlığı kötüye kullanımla ilgili olarak: Aslında her oturumda hataların olası maskelemesinden ziyade ortak geçerliliği kaçırmayla ilgili kaygılarım var, bu yüzden bu soru 'sahip olmaktan hoşnut' bir özellik. Test kodlarının gerçek blokları 10-100 satır UI otomasyon kodudur ve doğrulama hatalarından biri bloklardan birinde (veya yanlış blokta rapor edilmiş) atlanmış olduğundan, tespit edilmemiş kusurları tespit ettik. – Christoffer

cevap

1

varsa onun temizlenmesinden doğan bir finally bağlamda bekleyen ne istisna belirtmek için tip Exception bir parametre aldı IDisposable.Dispose bir aşırı yük olsaydı daha yararlı olurdu.Bir Dispose yöntemi genellikle istisnanın özelliklerini önemsemese de, arayana bildirilmesi gereken Dispose yöntemi sırasında koşullar ortaya çıkabilir. Dispose'dan atılan herhangi bir özel durum, arayanın finally bağlamında bekleyen herhangi bir özel durumun yerini alacaktır; bu nedenle, bir Dispose yönteminin, değiştirilmeden önce bekleyen bir istisnayı kapsülleyebilmesi yararlı olacaktır. Ne yazık ki böyle bir özellik mevcut değil ve eklenmesini beklemiyorum.

İstenilen efekt gibi bir şey elde etmek için kullanılabilecek bazı korsanlıklar olsa da, yalnızca semantik olarak doğru olan yöntem istisnanın Dispose yöntemine bir parametre olması içindir. Diğer bir yaklaşımdaki sorun, bir Dispose'un, iç içe geçmiş istisnai durumlara sahip olan ve bazıları bunlardan olmayan birden çok iç içe geçmiş finally blok içinden çalıştırılabilmesidir; En derin iç içe geçmiş finally bloğunun durumunu belirlemek için yürütme bağlamını inceleyen kod, bu blok atılan nesnenin ömrünü koruyan bir blok değilse başarısız olabilir.

+0

Bence bu cevabı en doğru olanı olarak kabul edeceğim – Christoffer

0

Bunu yapmanın kesin ve çirkin bir yolu, sınıfınızda bir boole (varsayılan yanlış) bulunmasıdır.

using (var managerSession = new Session(managerRole)) 
{ 
    Assert.IsTrue(managerSession.DoJob(), "Manager did not do his job"); 
    managerSession.NoExceptionThrown = true; 
} 

IDisposable deseniniz ile olduğundan daha fazla temizleyeceğinizi sanmıyorum.

Bu örnekte, bir ... yakalama ... son olarak, null-ness (bu bir sözcük mü?) Ve muhtemelen sınamak için istisna nesnesine doğrudan erişebildiğiniz için daha iyi çalışabilir hatta daha sonra kullanmak için saklayın. Hiçbir şey kaybetmemelisiniz çünkü using nihayet bir deneme yakalamak için şekerdir.

+1

Evet, nullness mükemmel bir kelime. – Christoffer

+0

Ve daha ciddi bir açıklama için, Dispose yöntemindeki doğrulama bloğunu kontrol eden bir özelliği ayarlamak aslında o kadar iyi bir fikir değildir. Yine de her kullanım bloğuna bir şey ekliyorsak, o zaman varolan doğrulama kodunu ayrı bir yönteme göre düzeltmek daha iyi olurdu ve yalnızca kapsamı kapatmadan önce bunu çağırın – Christoffer

+0

@Christoffer Evet, bir Kullanarak yuvarlak-plug-in-a-kare delikli bir şey. Supercat'in işaret ettiği gibi, uygun yol istisna nesnesini veya atılacak bir istisnanın meydana geldiğinin bir işaretini iletmektir. Öyleyse, uygun yöntemi ekleyebiliyorsunuz, sadece kullanımı atlayıp Dispose'ı (istisna) kendiniz mi çağırıyorsunuz? Orada da meseleler var, ve dilini gutting yapmadan tam olarak ne yapmak için yapmaya zorlayacağınızı ve kafasını geriye doğru tekrar bağlayabileceğinizi düşünmüyorum: c. Bildiğim kadarıyla, bir yakalama bloğu dışındaki herhangi bir istisnayı kontrol etmenin bir yolu yok. – Xcelled194

İlgili konular