2010-05-06 1 views
6

Я использую JUnit для написания тестов более высокого уровня для устаревшего кода, который не имеет модульных тестов.Есть ли способ заставить JUnit терпеть неудачу при любом неконтролируемом исключении, даже если проглотил

Большая часть этого кода «проглатывает» множество неконтролируемых исключений, таких как NullPointerExceptions (например, просто распечатывая трассировку стека и возвращая нуль). Поэтому единичный тест может пройти даже через каскад катастроф в разных точках кода нижнего уровня.

Есть ли способ провалить тест при первом неконтролируемом исключении, даже если они проглочены?

Единственная альтернатива, о которой я могу думать, это написать обычную оболочку JUnit, которая перенаправляет System.err, а затем анализирует вывод для исключений.

+4

Нет, как бы JUnit знал об исключении, если он проглотил до того, как код JUnit достигнут? Но, возможно, вы не должны полагаться на все, что происходит в устаревшем коде, и просто убедитесь, что ваш код верен.В конце концов, когда что-то пойдет не так, что влияет на результат вашего кода, ваш тест должен потерпеть неудачу. – FRotthowe

+0

@FRotthowe: Я использую JUnit для записи регрессионных тестов и тестов оболочки для существующих компонентов устаревшего кода. У меня нет моего собственного кода. проблема в том, что я хочу поймать эти внутренние сбои, тем более, что люди поддерживают внутренний код. – Uri

ответ

4

Если вы выполняете тесты в отладчике IDE, вы можете настроить IDE на разрыв при вызове исключения.

4

В отсутствии конкретного решения, мой ответ в довольно общем:

Такого код запахи (например, исключение swalling) лучше всего чистить шаг за шагом (класс по классу), когда вы столкнетесь с ними в то время как исправлением ошибок старой системы. Инструменты качества кода (например, Findbugs, PMD, Checkstyle или даже Sonar Quality Server) помогают вам находить эти вещи.

Способ «поймать» проглатываемые исключения автоматически должен использовать компилятор AspectJ. Вы можете объявлять аспекты для генерации ошибки времени компиляции в вашей среде IDE при нарушении определенных кодовых соглашений. В качестве альтернативы, вы можете переплетать во время выполнения тестируемых классов и позволить AspectJ реконструировать такие исключения, чтобы их можно было записать бегуном JUnit.

+1

+1 - У PMD уже есть правило искать пустые блоки catch. Вероятно, было бы непросто расширить это, чтобы правила могли искать другие распространенные способы отказа при обработке исключений. –

0

Можно было бы высмеивать Исключения, которые вы хотите поймать, с насмешливой структурой, которая изменяет байт-код или структуру AOP. Я предполагаю, что вы можете изменить конструктор, чтобы бросить более фатальное исключение или установить некоторый флаг в тестовом коде.

1

Я считаю, что исключение является стандартным классом в библиотеках SDK.

Если вы извлекли его, изменили его и поместили где-то в свой путь к классу перед SDK, я думаю, что он должен заменить тот, что в SDK (если вы не можете вернуть свое «новое» исключение в банку SDK)

В любом случае, ваше новое исключение может установить статическое значение, которое может быть прочитано с помощью среды тестирования.

Может быть не самым элегантным решением, но оно не требует какой-либо «Magic»

+0

Это не так просто, поскольку код находится в java. пакет, и у JDK есть некоторые механизмы безопасности, чтобы предотвратить такое вмешательство, с которым вам приходится работать. – Yishai

+0

@ Yishai Странно, я знал, что люди это делают, но не вникают в механику того, что они сделали. Мне нужно будет изучить его дальше ... (Посмотрев на это, эта страница, похоже, не согласна: http://forums.sun.com/thread.jspa?threadID=30607&tstart=3420) –

+0

yes Путь к загрузке основная идея, но это означало бы отдельно сделанный и скомпилированный класс, завернутый в отдельную банку или какую-нибудь другую фантазию, чтобы отделить эти реализации, а затем вы не можете связать этот класс с любыми другими классами (например, классом JUnit) и ваш тест должен назвать это, а не наоборот. Это выполнимо, так просто. – Yishai

1

Я хотел бы попробовать использовать АОП бросить неудачи. Нечто подобное должно работать (заметьте, я не проверял это, и вы obviouslly должны иметь установки AspectJ использовать АОП аннотаций)

public class ClassUnderTest 
{ 
    private static Boolean exceptionThrown; 


    @Before 
    public void resetExceptionFlag() 
    { 
     ClassUnderTest.exceptionThrown = false; 
    } 

    @Test 
    public void myTestMethod() 
    { 

     //.... 
     // My Test Exception Code 
     //.... 

     assertFalse(ClassUnderTest.exceptionThrown); 
    } 

    @Aspect 
    static class TestAspects 
    { 
     @Pointcut("handler(Exception)") 
     public void intereceptAllExceptions(){} 

     //This is Fully Qualified because of the conflict with the junit Before annotation above 
     @org.aspectj.lang.annotation.Before("intereceptAllExceptions()") 
     public void flagExceptionThrown() 
     { 
     ClassUnderTest.exceptionThrown = true; 

    } 

}}

0

Может быть, вы можете вставить код, который вам пытаются проверить. Скорее всего, вам придется использовать некоторые из «шаблонов тестирования», таких как powermock или jmockit, чтобы манипулировать манипулятором классов в JVM. Но образец тестируемого класса поможет определить необходимый подход.

 Смежные вопросы

  • Нет связанных вопросов^_^