2015-06-13 4 views
1

Я пытаюсь проверить свой класс на исключение. Я пробовал пару разных методов, ничего не работает. Что я здесь делаю неправильно?JUnit: Исключение проверки не работает (AssertionError: ожидаемое исключение, даже если выбрано исключение)

Класс Я пытаюсь проверить, PrimeNumber.java:

public class PrimeNumber { 

    static final Logger LOG = LogManager.getLogger("Log"); 

    private String primeNumberStr; 

    public PrimeNumber(String primeNumberStr) { 
     this.primeNumberStr = primeNumberStr; 
    } 

    public String getPrimeResult() { 
     String resultStr = ""; 
     try { 
      // Convert user input to int 
      int primeNumberInt = Integer.parseInt(primeNumberStr); 
      // Beginning of return message 
      resultStr += primeNumberInt + " is "; 
      // Add "not" if it's not a prime 
      if (!Primes.isPrime(primeNumberInt)) 
       resultStr += "NOT "; 
      // End return message 
      resultStr += "a prime"; 
      // If not a valid number, catch 
     } catch (NumberFormatException e) { 
      // Log exception 
      LOG.warn("NumberFormatException" + e.getMessage()); 
      // If empty user input 
      if (primeNumberStr.length() == 0) 
       resultStr += "No number inserted"; 
      // Else not empty but not valid 
      else 
       resultStr += primeNumberStr + " is not a valid number"; 
      resultStr += ". Only numbers without decimals are accepted."; 
     } 

     return resultStr; 
    } 

} 

А теперь то, что я пытался тест:

С аннотацией

@Test(expected = NumberFormatException.class) 
public void testNumberFormatExceptionBeingThrown() { 
    PrimeNumber primeNumber = new PrimeNumber("6dg"); 
    primeNumber.getPrimeResult(); 
} 

Результаты в не удалось испытания и:

java.lang.AssertionError: Expected exception: java.lang.Exception 

С помощью правила JUnit:

@Rule public ExpectedException thrown = ExpectedException.none(); 

@Test(expected = NumberFormatException.class) 
public void testNumberFormatExceptionBeingThrown() { 
    thrown.expect(NumberFormatException.class); 
    thrown.expectMessage("For input string: \"a21\""); 
    PrimeNumber primeNumber = new PrimeNumber("a21"); 
    primeNumber.getPrimeResult(); 
} 

Результаты в:

java.lang.AssertionError: Expected test to throw (an instance of java.lang.NumberFormatException and exception with message a string containing "For input string: \"a21\"") 
at org.junit.Assert.fail(Assert.java:88) 
at org.junit.rules.ExpectedException.failDueToMissingException(ExpectedException.java:263) 
at org.junit.rules.ExpectedException.access$200(ExpectedException.java:106) 
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:245) 
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
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:62) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 

+1

Ну, ни один из ваших методов, которые вы разместили, не выдает «NumberFormatException».Конечно, конструктор этого не делает. Почему ты так думаешь? Все, что вы делаете в конструкторе, присваивает 'String' полю' String'. Я в замешательстве, почему вы написали код, который делает все возможное, чтобы избежать исключений из-за того, что они были выброшены, а затем ожидать, что он будет генерировать исключения. –

+0

Забыл одну строку кода (вызов метода getPrimeResult()). Но я предполагаю, что я неправильно понял что-то о тестировании исключений. Таким образом, невозможно проверить исключение, которое было уловлено? Это то, что вы говорите? – asmb

+0

@asmb Вы проверяете метод с 'ожидаемым =', если этот метод распространяет это исключение на метод вызова. Таким образом, тестовый метод (или тестовый бегун) может его поймать и проверить, соответствует ли ожидаемое исключение. Если вы сами поймаете это исключение, вы не сможете проверить его так. – Tom

ответ

1

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

Это просто, не имеет смысла делать оба одновременно. Вам нужно решить, если вы хотите, чтобы каждый метод выдавал исключение или не получал неправильные аргументы.

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

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


Это говорит о том, что способ обработки чисел в вашем классе не имеет большого смысла. Вы получаете их как String s, сохраняя их как String s, и возвращаете их как String s, но всякий раз, когда вы работаете с ними, вы конвертируете их взад-вперед до int. Почему бы просто не использовать int везде в первую очередь?

1

Ваш getPrimeResult на самом деле имеем дело с исключением, а не позволяя ему распространяться дальше в стеке вызовов , Следовательно, это не бросается, и тест никогда не сможет перехватить его и утвердить против него (в этом состоянии).

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

// after the assignment to resultStr 
throw e;