Last active
December 29, 2015 13:39
-
-
Save arnehormann/7678580 to your computer and use it in GitHub Desktop.
some reflection magic to help writing table based tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import java.util.Arrays; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.fail; | |
public final class TestHelper { | |
public static void test(Object[][] tests, Object target, String methodName, Class<?>...argsTypes) throws Exception { | |
Class<?> baseClass; | |
if (target instanceof Class) { | |
// static method | |
baseClass = (Class<?>) target; | |
target = null; | |
} else { | |
baseClass = target.getClass(); | |
} | |
Method method = baseClass.getDeclaredMethod(methodName, argsTypes); | |
if (!method.isAccessible()) { | |
method.setAccessible(true); | |
} | |
// iterate over test data arrays (arguments for tested method followed by expected value) | |
// and if the expected value is a real value check and compare the result. | |
// If it's an Exception, catch it and compare class and message with expected Exception. | |
// This does not account for methods returning Exceptions. | |
try { | |
Object[] args = new Object[method.getGenericParameterTypes().length]; | |
for (int i = 0; i < tests.length; i++) { | |
Object[] test = tests[i]; | |
final String message = "case " + i + ": " + Arrays.toString(test); | |
// expected is always the last value | |
final Object expected = test[test.length - 1]; | |
System.arraycopy(test, 0, args, 0, test.length - 1); | |
try { | |
final Object actual = method.invoke(null, args); | |
if (actual == null || expected.getClass() != actual.getClass()) { | |
throw new RuntimeException("actual and expected values do not match in " + message); | |
} | |
// compare with expected int, Date, String, ... | |
assertEquals(message, expected, actual); | |
continue; | |
} catch (InvocationTargetException e) { | |
if (e.getTargetException().getClass() == expected.getClass()) { | |
// compare with expected Exception by class and message | |
assertEquals(message, | |
((Exception) expected).getMessage(), | |
e.getTargetException().getMessage() | |
); | |
continue; | |
} | |
// detailed exception message mentioning failed test case | |
throw new RuntimeException(message, e); | |
} | |
} | |
} catch (IllegalAccessException e) { | |
fail(e.getMessage()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And here is a helper method to mark unreachable code and get parameter information: