Test the error code of a custom exception with JUnit 4
Asked Answered
C

3

11

I would like to test the return code of an exception. Here is my production code:

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

And the corresponding exception:

class MyExceptionClass extends ... {
  private errorCode;

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

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

My unit test:

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();
  }
}
Crone answered 3/4, 2017 at 7:50 Comment(2)
Possible duplicate of JUnit right way of test expected exceptionsLeighton
I am looking for a nice way to do it. Try/catch is ok but it means more code lines. That is ugly to read in my point of view...Crone
I
14

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

That is all you need here:

  • you don't want to expect that specific exception, as you want to check some properties of it
  • you know that you want to enter that specific catch block; thus you simply fail when the call doesn't throw
  • you don't need any other checking - when the method throws any other exception, JUnit will report that as error anyway
Intermingle answered 3/4, 2017 at 8:25 Comment(0)
L
9

You can check for it using hamcres matchers as long as thrown.expect is overload to receive Matcher

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

Note that you will need to add hamcrest matcher to your dependencies. Core matched that are included in JUnit is not enough.

Or if you don't want to use CombinableMatcher:

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

Also, you don't need (expected = MyExceptionClass.class) declaration for @Test annotation

Leighton answered 3/4, 2017 at 8:39 Comment(0)
B
2

Expanding upon Sergii's answer, you can clean this up even more by writing a custom matcher.

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

The error code can then be checked like:

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

Reference: https://dzone.com/articles/testing-custom-exceptions

Birdcage answered 25/10, 2018 at 22:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.