0

While experimenting JUnit, I am trying to test a simple private method as follows, this method receives a String and make sure it does not include the word 'Dummy' in it.

I know, it is possible to put the test in the same package as the class and change access modifier of the method to package but I would like to use reflection to learn that.

private void validateString(String myString) throws CustomException {

    if (myString.toLowerCase().matches(".*dummy.*"))
        throw new CustomException("String has the invalid word!");

}

I am trying to access the private method through reflection but the test fails! It shows following exception:

java.lang.AssertionError:Expected test to throw
(an instance of com.myproject.exception.CustomException and exception 
with message a string containing "String has the invalid word!")

Based on answer of this question, I am catching InvocationTargetException as well.

JUnit

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

    @Test
    public void shouldThrowExceptionForInvalidString() {

        thrown.expect(CustomException.class);
        thrown.expectMessage("String has the invalid word!");

        try {
            MyClass myCls = new MyClass();
            Method valStr = myCls.getClass().getDeclaredMethod(
                    "validateString", String.class);
            valStr.setAccessible(true);
            valStr.invoke(myCls, "This is theDummyWord find it if you can.");
        } catch (InvocationTargetException | NoSuchMethodException
                | SecurityException | IllegalAccessException
                | IllegalArgumentException n) {
            if (n.getCause().getClass() == CustomException.class) {
                throw new CustomException("String has the invalid word!");
            }
        }

    }
Community
  • 1
  • 1
Jack
  • 6,430
  • 27
  • 80
  • 151
  • 1
    This makes no sense as a test. You are not testing a method, you are only testing the test itself. – Stultuske Sep 22 '15 at 06:26
  • @Stultuske I see would you elaborate on that? how to test the method then? – Jack Sep 22 '15 at 06:27
  • if you want to use expectedException, drop the try-catch, and add a throws clause. You don't want to test whether your test throws that Exception but your method. – Stultuske Sep 22 '15 at 06:28
  • Another way: catch(Exception e){ assert(e instanceof CustomException); } and add a test for the message of the Exception – Stultuske Sep 22 '15 at 06:29
  • @Stultuske I am a bit confused would you please post that as an answer? – Jack Sep 22 '15 at 06:31
  • since it's not a complete answer to your question, that wouldn't be recommended. but my point is: this -> thrown.expect(CustomException.class); thrown.expectMessage("String has the invalid word!"); will test the Exception thrown by your test itself. What's the point of that? – Stultuske Sep 22 '15 at 06:34
  • When I run the test it returns InvocationTargetException thats why I am catching that. Also I need to catch other exceptions otherwise it wont compile. – Jack Sep 22 '15 at 06:36

1 Answers1

1

I agree with @Stultuske in the comments above and would rewrite the test to:

@Test
public void shouldThrowExceptionForInvalidString() {

    try {
        MyClass myCls = new MyClass();
        Method valStr = myCls.getClass().getDeclaredMethod(
                "validateString", String.class);
        valStr.setAccessible(true);
        valStr.invoke(myCls, "This is theDummyWord find it if you can.");
    } catch (Exception e) {
        assert(e instanceOf CustomException);
        assert(e.getMessage.equals("String has the invalid word!"));
    }

}

Or if you want to use ExpectedException

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

@Test
public void shouldThrowExceptionForInvalidString() {

    thrown.expect(CustomException.class);
    thrown.expectMessage("String has the invalid word!");

    MyClass myCls = new MyClass();
    Method valStr = myCls.getClass().getDeclaredMethod("validateString", String.class);
    valStr.setAccessible(true);
    valStr.invoke(myCls, "This is theDummyWord find it if you can.");

}
Glennie Helles Sindholt
  • 12,816
  • 5
  • 44
  • 50