2015-04-21 4 views
4

У меня есть функция, которая возвращает исключение, и я пишу блок-блок для него в Junit4. Проблема заключается в том, что reflect.invoke всегда завершает исключение в InvocationTargetException и, следовательно, не может проверить исключение, используя класс ExpectedException.Тестирование Исключения с использованием Java Reflection Junit4

public class Hello { 
private void printHello(String msg) { 
    if ("hello".equals(msg)) { 
     System.out.println("Hello"); 
    } 
     else throw new HeaderException(); 
    } 
} 

Тест:

@Rule 
public ExpectedException expectedEx = ExpectedException.none(); 
@Test 
public void testPrint() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 
    expectedEx.expect(HeaderException.class); 

    Method method = Hello.class.getDeclaredMethod("printHello", String.class); 
    method.setAccessible(true); 
    method.invoke(Hello.class,"random"); 

} 

Выход:

java.lang.AssertionError: 
Expected: an instance of com.locationguru.CSF.exception.HeaderException 
    got: <java.lang.reflect.InvocationTargetException> 
<Click to see difference> 

    at org.junit.Assert.assertThat(Assert.java:780) 
    at org.junit.Assert.assertThat(Assert.java:738) 
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:114) 
    at org.junit.rules.RunRules.evaluate(RunRules.java:18) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
+0

Возможные дубликат http://stackoverflow.com/questio ns/871216/junit-possible-to-expect-a-wrapped-exception – Marvin

+0

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

+0

Сначала я подумал, что 'expectedEx.expectCause (instanceOf (HeaderException.class));' сделал бы это, но, к сожалению, исключение HeaderException не хранится в 'cause', а в' target'. Я предлагаю вам написать собственный Matcher или выполнить поиск в Интернете для общего ExceptionMatcher. – CoronA

ответ

3

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

try 
    { 
     method.invoke(Hello.class, "random"); 
    } 
    catch (InvocationTargetException e) 
    { 
     throw e.getTargetException(); 
    } 
Смежные вопросы