Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Java | JUnit4でEnclosed,Theory,DataPoints対応のテストコードの雛形を自動生成

パンくず

Java
JUnit4でEnclosed,Theory,DataPoints対応のテストコードの雛形を自動生成

概要

JUnit4でEnclosed,Theory,DataPoints対応のテストコードの雛形を自動生成

内容

JUnit4かつ以下の形式のテストコードの雛形を生成します。

・クラス名はテスト対象クラス名+Test
・publicメソッドごとにインナークラスを作成
・各インナークラスごとにFixtureとDataPointsを生成
・インタークラス名はメソッド名の頭を大文字にしたもの

サンプルコード

import java.lang.reflect.Method;

import theory_sample.TheoriesSample;

public class JUnit4ClassGenerator {
  static final String PACKAGE = "$package";
  static final String CLASS = "$class_name";
  static final String METHODS = "$methods";
  static final String METHOD_NAME = "$method_name";

  public static final String TEMPLATE ="$package;\n"
      + "\n"
      + "import static jp.co.dgic.testing.framework.DJUnitTestCase.setReturnValueAtAllTimes;\n"
      + "import static org.hamcrest.CoreMatchers.is;\n"
      + "import static org.junit.Assert.assertThat;\n"
      + "\n"
      + "import org.junit.experimental.runners.Enclosed;\n"
      + "import org.junit.experimental.theories.DataPoints;\n"
      + "import org.junit.experimental.theories.Theories;\n"
      + "import org.junit.experimental.theories.Theory;\n"
      + "import org.junit.runner.RunWith;\n"
      + "\n"
      + "@RunWith(Enclosed.class)\n"
      + "public class $class_nameTest {\n"
      + "\n"
      + "$methods"
      + "\n"
      + "}";

  public static final String METHOD_TEMPLATE = "    // TODO publicメソッドごとのテストを実装\n"
    + "    @RunWith(Theories.class)\n"
    + "    public static class $method_name{\n"
    + "\n"
    + "        // TODO テストデータをFixtureの配列に追加\n"
    + "        @DataPoints\n"
    + "        public static Fixture[] getFixture() {\n"
    + "            Fixture[] fixture = { \n"
    +"\n"
    + "            };\n"
    + "            return fixture;\n"
    + "        };\n"
    + "\n"
    + "        // TODO テストメソッドのコメントを追加\n"
    + "        @Theory\n"
    + "        public void test$method_name(Fixture fixture) {\n"
    + "            // TODO テストコードを実装\n"
    + "        }\n"
    + "\n"
    + "        static class Fixture {\n"
    + "            Fixture() {\n"
    + "\n"
    + "            }\n"
    + "\n"
    + "            public String toString() {\n"
    + "                return null;\n"
    + "            }\n"
    + "        }\n"
    + "    }\n";

  public static void outputJUnit4Class(Class<?> clazz) {
    String code = TEMPLATE;
    code = code.replace(PACKAGE, clazz.getPackage().toString());
    code = code.replace(CLASS, clazz.getSimpleName());

    Method[] methods = clazz.getMethods();
    StringBuilder sb = new StringBuilder();
    for (Method method : methods) {
      // Objectクラスから継承したメソッドはテスト対象外
      if (isObjectsMethod(method)) {
        continue;
      }
      String methodName = getMethodName(method);
      sb.append(METHOD_TEMPLATE.replace(METHOD_NAME, methodName));
      sb.append("\n");
    }
    System.out.println(code.replace(METHODS, sb.toString()));
  }

  private static boolean isObjectsMethod(Method method) {
    return (method.getDeclaringClass() == Object.class);
  }

  private static String getMethodName(Method method) {
    String methodName = method.getName();
    return methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
  }

  public static void main(String[] args) {
    // テスト対象のクラス名とFixtureに保持させる変数の型、変数名を設定
    outputJUnit4Class(TheoriesSample.class);
  }
}

出力

※テスト対象クラスのTheoriesSampleはGetNameとGetNameSanの2publicメソッドを持っています。

package theory_sample;

import static jp.co.dgic.testing.framework.DJUnitTestCase.setReturnValueAtAllTimes;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.experimental.runners.Enclosed;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

@RunWith(Enclosed.class)
public class TheoriesSampleTest {

    // TODO publicメソッドごとのテストを実装
    @RunWith(Theories.class)
    public static class GetName{

        // TODO テストデータをFixtureの配列に追加
        @DataPoints
        public static Fixture[] getFixture() {
            Fixture[] fixture = { 

            };
            return fixture;
        };

        // TODO テストメソッドのコメントを追加
        @Theory
        public void testGetName(Fixture fixture) {
            // TODO テストコードを実装
        }

        static class Fixture {
            Fixture() {

            }

            public String toString() {
                return null;
            }
        }
    }

    // TODO publicメソッドごとのテストを実装
    @RunWith(Theories.class)
    public static class GetNameSan{

        // TODO テストデータをFixtureの配列に追加
        @DataPoints
        public static Fixture[] getFixture() {
            Fixture[] fixture = { 

            };
            return fixture;
        };

        // TODO テストメソッドのコメントを追加
        @Theory
        public void testGetNameSan(Fixture fixture) {
            // TODO テストコードを実装
        }

        static class Fixture {
            Fixture() {

            }

            public String toString() {
                return null;
            }
        }
    }


}