2010-09-13 10 views
9

% 100 kod kapsamı girişimlerinde, bir InterruptedException yakalayan kod birim bloğuna ihtiyacım olan bir durumla karşılaştım. Biri bunu nasıl doğru bir şekilde test eder?"InterruptedException" için birim testi nasıl yazılır

private final LinkedBlockingQueue<ExampleMessage> m_Queue; 

public void addMessage(ExampleMessage hm) { 
    if(hm!=null){ 
     try { 
      m_Queue.put(hm); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

cevap

13

Sağ addMessage() çağırmadan önce (JUnit 4 sözdizimi lütfen), Thread.currentThread().interrupt() diyoruz. Bu iş parçacığı üzerinde "kesme" durum işaretini ayarlayacaktır. put() çağrısı bir LinkedBlockingQueue üzerinde yapıldığında kesintiye durum ayarlanırsa

, bir InterruptedException bekleme put için gerekli olsa bile yükseltilecek (kilit un-sürmüştür). Bu arada,% 100'lük kapsama ulaşmak için bazı çabalar, karşı-üretkendir ve aslında kodun kalitesini düşürebilirler.

+1

+1, bu doğrudur. 80-85'i hedefleyin ve bu gibi sorunların hepsinden sakınacaksınız ve kodunuzu oldukça bozulmamış halde tutabileceksiniz. – BjornS

+1

Bu oldukça acımasız bir çözüm ve beklenmedik yan etkilere sahip olabilir. Örneğin, bir test yönteminde Thread.currentThread(). Interrupt() öğesinin çağrılmasının tüm sınama yöntemlerini aynı sınıfta etkileyeceğini ve diğer tüm sınamaların başarısız olmasına neden olduğunu buldum. Bunu, herhangi bir test sınıfına eklediğimde, Sonar'ın% 0 ünite test kapsamını rapor etmesine neden olduğunu buldum (nedenini bulamadı). – RCross

+0

Evet, kullandığınız yere dikkat etmelisiniz, kesme durumunun temizleneceğinden (burada olduğu gibi) ve ayarınız ile testinizin kontrol edilmesi arasındaki durumun araya girip girmediğini kontrol etmelisiniz. – erickson

9

EasyMock gibi alaycı bir kitaplık kullanın ve gerek kalmaz,

yani

@Test(expect=InterruptedException.class) 
public void testInterruptedException() { 
    LinkedBlockingQueue queue = EasyMock.createMock(LinkedBlockingQueue.class); 
    ExampleMessage message = new ExampleMessage(); 
    queue.put(message); 
    expectLastCall.andThrow(new InterruptedException()); 
    replay(queue); 
    someObject.setQueue(queue); 
    someObject.addMessage(msg); 
} 
+0

Kesinlikle en iyi yol. Bundan daha birçok sorunu çözer. –

1

Diğer bir seçenek Guava 'ın Uninterruptibles için InterruptedException uğraşan aktarmaktır sahte LinkedBlockingQueue enjekte Bunun için özel kodunuzu yazıp test edin:

import static com.google.common.util.concurrent.Uninterruptibles.putUninterruptibly; 

private final LinkedBlockingQueue<ExampleMessage> queue; 

public void addMessage(ExampleMessage message) { 
    putUninterruptibly(queue, message); 
}