Проверьте код ошибки пользовательского исключения с JUnit 4

Я хотел бы проверить код возврата исключения. Вот мой производственный код:

class A {
  try {
    something...
  }
  catch (Exception e)
  {
    throw new MyExceptionClass(INTERNAL_ERROR_CODE, e);
  }
}

И соответствующее исключение:

class MyExceptionClass extends ... {
  private errorCode;

  public MyExceptionClass(int errorCode){
    this.errorCode = errorCode;
  }

  public getErrorCode(){ 
    return this.errorCode;
  }
}

Мой юнит тест:

public class AUnitTests{
  @Rule
  public ExpectedException thrown= ExpectedException.none();

  @Test (expected = MyExceptionClass.class, 
  public void whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode() throws Exception {
      thrown.expect(MyExceptionClass.class);
      ??? expected return code INTERNAL_ERROR_CODE ???

      something();
  }
}

3 ответа

Решение

Просто:

 @Test 
 public void whenSerialNumberIsEmpty_shouldThrowSerialNumberInvalid() throws Exception {
  try{
     whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode();     
     fail("should have thrown");
  }
  catch (MyExceptionClass e){
     assertThat(e.getCode(), is(MyExceptionClass.INTERNAL_ERROR_CODE));
  }

Это все, что вам нужно здесь:

  • вы не хотите ожидать этого конкретного исключения, так как вы хотите проверить некоторые его свойства
  • вы знаете, что хотите войти в этот конкретный блок catch; таким образом, вы просто терпите неудачу, когда вызов не бросает
  • вам не нужна никакая другая проверка - когда метод выдает любое другое исключение, JUnit все равно сообщит об этом как об ошибке

Вы можете проверить это, используя Hamcres Matchers до тех пор, пока thrown.expect перегружен, чтобы получить Matcher

thrown.expect(CombinableMatcher.both(
           CoreMatchers.is(CoreMatchers.instanceOf(MyExceptionClass.class)))
           .and(Matchers.hasProperty("errorCode", CoreMatchers.is(123))));

Обратите внимание, что вам нужно добавить Hamcrest Matcher к вашим зависимостям. Подходящего ядра, включенного в JUnit, недостаточно.

Или, если вы не хотите использовать CombinableMatcher:

thrown.expect(CoreMatchers.instanceOf(MyExceptionClass.class));
thrown.expect(Matchers.hasProperty("errorCode", CoreMatchers.is(123));

Кроме того, вам не нужно (expected = MyExceptionClass.class) декларация для @Test аннотирование

Разобравшись с ответом Сергея, вы можете еще больше разобраться в этом, написав специальное сопоставление.

import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;

public class CustomMatcher extends TypeSafeMatcher<CustomException> {

    public static CustomMatcher hasCode(String item) {
        return new CustomMatcher(item);
    }

    private String foundErrorCode;
    private final String expectedErrorCode;

    private CustomMatcher(String expectedErrorCode) {
        this.expectedErrorCode = expectedErrorCode;
    }

    @Override
    protected boolean matchesSafely(final CustomException exception) {
        foundErrorCode = exception.getErrorCode();
        return foundErrorCode.equalsIgnoreCase(expectedErrorCode);
    }

    @Override
    public void describeTo(Description description) {
        description.appendValue(foundErrorCode)
                .appendText(" was not found instead of ")
                .appendValue(expectedErrorCode);
    }
}

Код ошибки может быть проверен следующим образом:

import org.junit.rules.ExpectedException;

public class MyObjTest {

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

    @Test
    public void someMethodThatThrowsCustomException() {
        thrown.expect(CustomException.class);
        thrown.expect(CustomMatcher.hasCode("110501"));

        MyObj obj = new MyObj();
        obj.methodThatThrowsCustomException();
    }
}

Ссылка: https://dzone.com/articles/testing-custom-exceptions

Другие вопросы по тегам