Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Ok, here is a quick mock-up of how JUnit 4 runs parameterized tests, but done in JUnit 3.8.2.</p> <p>Basically I'm subclassing and badly hijacking the TestSuite class to populate the list of tests according to the cross-product of testMethods and parameters. </p> <p>Unfortunately I've had to copy a couple of helper methods from TestSuite itself, and a few details are not perfect, such as the names of the tests in the IDE being the same across parameter sets (JUnit 4.x appends <code>[0]</code>, <code>[1]</code>, ...).</p> <p>Nevertheless, this seems to run fine in the text and AWT <code>TestRunner</code>s that ship with JUnit as well as in Eclipse.</p> <p>Here is the ParameterizedTestSuite, and further down a (silly) example of a parameterized test using it.</p> <p>(final note : I've written this with Java 5 in mind, it <em>should</em> be trivial to adapt to 1.4 if needed)</p> <p><em>ParameterizedTestSuite.java:</em></p> <pre><code>package junit.parameterized; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class ParameterizedTestSuite extends TestSuite { public ParameterizedTestSuite( final Class&lt;? extends TestCase&gt; testCaseClass, final Collection&lt;Object[]&gt; parameters) { setName(testCaseClass.getName()); final Constructor&lt;?&gt;[] constructors = testCaseClass.getConstructors(); if (constructors.length != 1) { addTest(warning(testCaseClass.getName() + " must have a single public constructor.")); return; } final Collection&lt;String&gt; names = getTestMethods(testCaseClass); final Constructor&lt;?&gt; constructor = constructors[0]; final Collection&lt;TestCase&gt; testCaseInstances = new ArrayList&lt;TestCase&gt;(); try { for (final Object[] objects : parameters) { for (final String name : names) { TestCase testCase = (TestCase) constructor.newInstance(objects); testCase.setName(name); testCaseInstances.add(testCase); } } } catch (IllegalArgumentException e) { addConstructionException(e); return; } catch (InstantiationException e) { addConstructionException(e); return; } catch (IllegalAccessException e) { addConstructionException(e); return; } catch (InvocationTargetException e) { addConstructionException(e); return; } for (final TestCase testCase : testCaseInstances) { addTest(testCase); } } private Collection&lt;String&gt; getTestMethods( final Class&lt;? extends TestCase&gt; testCaseClass) { Class&lt;?&gt; superClass= testCaseClass; final Collection&lt;String&gt; names= new ArrayList&lt;String&gt;(); while (Test.class.isAssignableFrom(superClass)) { Method[] methods= superClass.getDeclaredMethods(); for (int i= 0; i &lt; methods.length; i++) { addTestMethod(methods[i], names, testCaseClass); } superClass = superClass.getSuperclass(); } return names; } private void addTestMethod(Method m, Collection&lt;String&gt; names, Class&lt;?&gt; theClass) { String name= m.getName(); if (names.contains(name)) return; if (! isPublicTestMethod(m)) { if (isTestMethod(m)) addTest(warning("Test method isn't public: "+m.getName())); return; } names.add(name); } private boolean isPublicTestMethod(Method m) { return isTestMethod(m) &amp;&amp; Modifier.isPublic(m.getModifiers()); } private boolean isTestMethod(Method m) { String name= m.getName(); Class&lt;?&gt;[] parameters= m.getParameterTypes(); Class&lt;?&gt; returnType= m.getReturnType(); return parameters.length == 0 &amp;&amp; name.startsWith("test") &amp;&amp; returnType.equals(Void.TYPE); } private void addConstructionException(Exception e) { addTest(warning("Instantiation of a testCase failed " + e.getClass().getName() + " " + e.getMessage())); } } </code></pre> <p><em>ParameterizedTest.java:</em></p> <pre><code>package junit.parameterized; import java.util.Arrays; import java.util.Collection; import junit.framework.Test; import junit.framework.TestCase; import junit.parameterized.ParameterizedTestSuite; public class ParameterizedTest extends TestCase { private final int value; private int evilState; public static Collection&lt;Object[]&gt; parameters() { return Arrays.asList( new Object[] { 1 }, new Object[] { 2 }, new Object[] { -2 } ); } public ParameterizedTest(final int value) { this.value = value; } public void testMathPow() { final int square = value * value; final int powSquare = (int) Math.pow(value, 2) + evilState; assertEquals(square, powSquare); evilState++; } public void testIntDiv() { final int div = value / value; assertEquals(1, div); } public static Test suite() { return new ParameterizedTestSuite(ParameterizedTest.class, parameters()); } } </code></pre> <p>Note: the <code>evilState</code> variable is just here to show that all test instances are different as they should be, and that there is no shared state between them.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload