问题
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!");
}
}
}
回答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.");
}
来源:https://stackoverflow.com/questions/32709784/cannot-test-a-class-that-return-a-customexception