5 votes

Tester le code d'erreur d'une exception personnalisée avec JUnit 4

Je voudrais tester le code de retour d'une exception. Voici mon code de production :

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

Et l'exception correspondante :

class MyExceptionClass extends ... {
  private errorCode;

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

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

Mon test unitaire :

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();
  }
}

6voto

GhostCat Points 83269

Simple :

 @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));
  }

C'est tout ce dont vous avez besoin ici :

  • vous ne voulez pas s'attendre à cette exception spécifique, comme vous vouloir pour en vérifier certaines propriétés
  • vous savez que vous vouloir pour entrer que spécifique ; vous échouez donc simplement lorsque l'appel ne déclenche pas de blocage.
  • vous n'avez pas besoin d'autres vérifications - lorsque la méthode lève une autre exception, JUnit la signale de toute façon comme une erreur

2voto

Sergii Bishyr Points 4342

Vous pouvez le vérifier à l'aide des outils de comparaison de hamcres, à condition que les conditions suivantes soient remplies thrown.expect est surchargé pour recevoir Matcher

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

Notez que vous devrez ajouter hamcrest matcher à vos dépendances. Le core matcher qui est inclus dans JUnit n'est pas suffisant.

Ou si vous ne voulez pas utiliser CombinableMatcher :

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

De plus, vous n'avez pas besoin (expected = MyExceptionClass.class) déclaration pour @Test annotation

1voto

mad_fox Points 871

En développant la réponse de Sergii, vous pouvez nettoyer cela encore plus en écrivant un matcheur personnalisé.

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);
    }
}

Le code d'erreur peut alors être vérifié comme suit :

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();
    }
}

Référence : https://dzone.com/articles/testing-custom-exceptions

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X