はじめに
MavenのプロジェクトでJUnitを利用するときに、毎回同じようなpom.xmlとテストコードを書いている。 なので、テンプレートとしてサンプルコードを書き残しておく。 このサンプルコードでは、割り算の処理をテストしている。
ディレクトリ構成
test-template |-- pom.xml `-- src |-- main | `-- java | `-- redj | `-- junit | `-- Calc.java `-- test `-- java `-- redj `-- junit `-- CalcTest.java
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>redj-junit</groupId> <artifactId>test-template</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <!-- configurations --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!-- dependency versions --> <junit.version>4.12</junit.version> <hamcrest.version>1.3</hamcrest.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <version>${hamcrest.version}</version> <scope>test</scope> </dependency> </dependencies> </project>
Calc.java
テスト対象のクラスで、割り算を行うクラス。 バグを表現するため、わざと絶対値をとってから割っている。
package redj.junit; public class Calc { public static int divide(int x, int y) { return x / Math.abs(y); // BUG: This line should be "return x / y;" } }
CalcTest.java
package redj.junit; import java.util.ArrayList; import java.util.List; import static org.hamcrest.core.Is.*; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; @RunWith(Enclosed.class) public class CalcTest { @RunWith(Parameterized.class) public static class DevideTest { @Parameters public static Iterable<Fixture> data() { List<Fixture> fixtures = new ArrayList<>(); fixtures.add(new Fixture(4, 2, 2, null)); fixtures.add(new Fixture(4, 0, 0, ArithmeticException.class)); fixtures.add(new Fixture(4, -2, -2, null)); return fixtures; } @Parameter public Fixture fixture; @Rule public ExpectedException expectedException = ExpectedException.none(); @Before public void setUp() { if (fixture.exceptionClass != null) { expectedException.expect(fixture.exceptionClass); } } @Test public void test() { int actual = Calc.divide(fixture.x, fixture.y); assertThat(actual, is(fixture.expected)); } public static class Fixture { public final int x; public final int y; public final int expected; public final Class<? extends Throwable> exceptionClass; public Fixture(int x, int y, int expected, Class<? extends Throwable> exceptionClass) { this.x = x; this.y = y; this.expected = expected; this.exceptionClass = exceptionClass; } } } }
実行結果
$ mvn clean install (略) ------------------------------------------------------- T E S T S ------------------------------------------------------- Running redj.junit.CalcTest Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.224 sec <<< FAILURE! test[2](redj.junit.CalcTest$DevideTest) Time elapsed: 0.012 sec <<< FAILURE! java.lang.AssertionError: Expected: is <-2> but: was <2> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) at org.junit.Assert.assertThat(Assert.java:956) at org.junit.Assert.assertThat(Assert.java:923) at redj.junit.CalcTest$DevideTest.test(CalcTest.java:51) (略) Results : Failed tests: test[2](redj.junit.CalcTest$DevideTest): (..) Tests run: 3, Failures: 1, Errors: 0, Skipped: 0 (略)