2010-09-13 6 views
9

В попытках покрытия 100% кода я столкнулся с ситуацией, когда мне нужно блок тестового блока кода, который ловит InterruptedException. Как правильно это проверить? (JUnit 4 синтаксис пожалуйста)Как написать модульный тест для «InterruptedException»

private final LinkedBlockingQueue<ExampleMessage> m_Queue; 

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

ответ

13

Прямо перед вызовом addMessage(), вызовите Thread.currentThread().interrupt(). Это установит флаг состояния прерывания в потоке.

Если прерванное состояние устанавливается, когда вызов put() сделан на LinkedBlockingQueue, InterruptedException будет поднят, даже если ожидания не требуется для put (замка ООН-утверждали).

Кстати, некоторые усилия по достижению 100% -ного охвата являются контрпродуктивными и могут фактически ухудшить качество кода.

+1

+1, это правда. Стремитесь к 80-85, и вы обойдете все проблемы, подобные этому, и сохраните свой код довольно нетронутым. – BjornS

+1

Это довольно жестокое решение и может иметь неожиданные побочные эффекты. Например, я обнаружил, что вызов Thread.currentThread(). Interrupt() в одном методе тестирования повлияет на все методы тестирования в том же классе, в результате чего все остальные тесты будут терпеть неудачу. Я также обнаружил, что добавление этого в любой тестовый класс приведет к тому, что Sonar сообщит о покрытии 0% единиц тестирования (не обнаружили, почему). – RCross

+0

Да, вам нужно быть осторожным, когда вы его использовали, убедившись, что статус прерывания будет очищен (как он есть здесь) и что нет промежуточной проверки состояния между вашим параметром и проверкой его теста. – erickson

9

Используйте насмешливую библиотеку как EasyMock и придать макет LinkedBlockingQueue

т.е.

@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

Абсолютно лучший способ. Решает еще много проблем, чем это. –

1

Другим вариантом заключается в делегировании дела с InterruptedException в гуавах «s Uninterruptibles, так что вам не нужно напишите и протестируйте свой код для него:

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

private final LinkedBlockingQueue<ExampleMessage> queue; 

public void addMessage(ExampleMessage message) { 
    putUninterruptibly(queue, message); 
} 
Смежные вопросы