今回は引数のオブジェクトのフィールドを適当な値で埋めるメソッドです。
JUnitで「あるオブジェクトに対してなんでもいいからとりあえずフィールド埋めている状態にしたい、でもいちいちsetter呼ぶの面倒臭すぎ!」ってことよくありますよね。そういう時に適当にフィールドに値を詰めてくれるメソッドを作ってみました。
前回作ったもの→プライベートメソッドを実行するやつ
作成したユーティリティメソッド
ReflectionUtil.java
public static void fillAllFields(Object obj, int offset) throws IllegalArgumentException, IllegalAccessException {
Assertions.assertThat(offset >= 0);
boolean b = true;
char c=(char) (65 + offset); // A+
Field[] fieldList = obj.getClass().getDeclaredFields();
for (int i = 0; i < fieldList.length; i++) {
int num = i + offset;
Field f = fieldList[i];
f.setAccessible(true);
String name = f.getName();
Class<?> clazz = f.getType();
if (Modifier.isFinal(f.getModifiers())) {
continue;
}
if (clazz == String.class) {
f.set(obj, name + num);
} else if (clazz == Date.class) {
Calendar calendar = Calendar.getInstance();
int d = num % 28;
calendar.set(2019, Calendar.MARCH, d);
f.set(obj, calendar.getTime());
} else if (clazz == Timestamp.class) {
Calendar calendar = Calendar.getInstance();
int d = num % 28;
calendar.set(2019, Calendar.MARCH, d);
f.set(obj, new Timestamp(calendar.getTimeInMillis()));
} else if(clazz==boolean.class ||clazz==Boolean.class ){
f.set(obj, b);
b=!b;
} else if(clazz==BigDecimal.class){
f.set(obj, new BigDecimal(num));
} else if(clazz==int.class||clazz==Integer.class){
f.set(obj, num);
} else if(clazz==long.class||clazz==Long.class){
f.set(obj, ((Integer) num).longValue());
} else if(clazz==float.class||clazz==Float.class){
f.set(obj, ((Integer) num).floatValue());
} else if(clazz==double.class||clazz==Double.class){
f.set(obj, ((Integer) num).doubleValue());
} else if(clazz==short.class||clazz==Short.class){
f.set(obj, ((Integer) num).shortValue());
} else if(clazz==byte.class||clazz==Byte.class){
f.set(obj, ((Integer) num).byteValue());
} else if(clazz==char.class||clazz==Character.class){
if (c < 65 || 90 < c) c = 65;
f.set(obj, ((char) c));
c++;
}
}
}
動かしてみる
適当なPOJOを用意
EntityA.java
@Data
public class EntityA {
private String str;
private Date date;
private Timestamp ts;
private Boolean bool;
private BigDecimal bd;
private Integer i;
private long l;
private Float f;
private double d;
private Short s;
private byte b;
private Character c;
}
テストメソッド
Tests.java
@Test
public void test1() {
EntityA entity= new EntityA();
try {
ReflectionUtil.fillAllFields(entity, 25);
System.out.println(entity);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
fail();
}
}
実行結果
コンソール
EntityA(str=str25, date=Tue Mar 26 02:05:01 JST 2019, ts=2019-03-27 02:05:01.786, bool=true, bd=29, i=30, l=31, f=32.0, d=33.0, s=34, b=35, c=Z)
あとがき
ミソはcharの場合にどうするかですね。このメソッドでは大文字のアルファベットA-Zに絞っています。
他のクラスは必要に応じて随時追加ですね。
境界値の検証してないのでバグあったらすみません。
おもいっきりレガシーなJavaメソッドになったけど、本当は出来る限りJava8を取り入れたかった。
というか、そもそもこんなユーティリティは何かのライブラリにあったりしそう??