Created
January 3, 2020 17:37
-
-
Save samuellb/5ea8eccdd28fd5a3e46a455e4a82260f to your computer and use it in GitHub Desktop.
Showing why @ Test(expected=...) in JUnit is an anti-pattern
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
/* | |
* Licensed under CC0 | |
* http://creativecommons.org/publicdomain/zero/1.0/ | |
*/ | |
package se.kodafritt.snippets.antipatterns; | |
import static org.hamcrest.CoreMatchers.isA; | |
import org.junit.BeforeClass; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.rules.ExpectedException; | |
import org.junit.rules.TestRule; | |
/** | |
* A demonstration of why Test(expected=...) and ExpectedException | |
* in unit tests is an anti-pattern. | |
*/ | |
public final class BadTest { | |
@Rule | |
public ExpectedException expectedException = ExpectedException.none(); | |
// This would be a separate class. | |
// Included inside the test to keep the example in one file. | |
public static final class ThingToTst { | |
private final int[] array; | |
public ThingToTst(final int[] array) { | |
this.array = array; | |
} | |
public int getElement(int index) { | |
return array[0]; // bug! but will the test catch it? | |
} | |
} | |
// try commenting out the thing.getElement calls below | |
@Test(expected = ArrayIndexOutOfBoundsException.class) | |
public void badTestOne() throws Exception { | |
final int[] array = makeArrayToTest(3); | |
final ThingToTst thing = new ThingToTst(array); | |
thing.getElement(3); // <-- the out of bounds occurs at this line, right? or, maybe it does not? | |
} | |
@Test | |
public void badTestTwo() throws Exception { | |
expectedException.expect(isA(ArrayIndexOutOfBoundsException.class)); | |
final int[] array = makeArrayToTest(3); | |
final ThingToTst thing = new ThingToTst(array); | |
thing.getElement(3); // <-- the out of bounds occurs at this line, right? or, maybe it does not? | |
} | |
public int[] makeArrayToTest(int length) { | |
int[] array = new int[length]; | |
for (int i = 0; i < length; i--) { | |
array[i] = i; | |
} | |
return array; | |
} | |
} |
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
<!-- | |
Here is a Ant build file in case you want to run the test. | |
Place the .java file under "java/test/se/kodafritt/snippets/antipatterns/". | |
You also need junit and hamcrest-core JARs in "lib/". | |
Tested with JUnit 4.11 and hamcrest-core 1.3. | |
--> | |
<project name="badtest" default="test"> | |
<path id="classpath"> | |
<fileset dir="lib"> | |
<include name="junit-*.jar"/> | |
<include name="hamcrest-core-*.jar"/> | |
</fileset> | |
</path> | |
<target name="build-test"> | |
<mkdir dir="build-test"/> | |
<javac classpathref="classpath" srcdir="java/test" destdir="build-test" includeantruntime="false" encoding="UTF-8"/> | |
</target> | |
<target name="test" depends="build-test"> | |
<mkdir dir="reports"/> | |
<junit printsummary="yes" haltonfailure="no"> | |
<classpath> | |
<path refid="classpath"/> | |
<path location="build-test"/> | |
</classpath> | |
<formatter type="xml"/> | |
<batchtest fork="yes" todir="reports"> | |
<fileset dir="build-test"> | |
<include name="**/*Test.class"/> | |
</fileset> | |
</batchtest> | |
</junit> | |
<mkdir dir="reports/html"/> | |
<junitreport todir="reports"> | |
<fileset dir="reports"> | |
<include name="TEST-*.xml"/> | |
</fileset> | |
<report format="noframes" todir="reports/html"/> | |
</junitreport> | |
</target> | |
<target name="clean"> | |
<delete dir="build-test"/> | |
<delete dir="reports"/> | |
</target> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment