I've got the following JUnit test:
@Test
public void calculateIntegerSum() {
// given
ValueSupplier supplier = new ValueSupplier();
TestClass1 testClass1 = createTestClass1(supplier);
TestClass2 testClass2 = createTestClass2(supplier);
TestClass3 testClass3 = createTestClass3(supplier);
TestClass4 testClass4 = createTestClass4(supplier);
testClass2.setTestClass1(testClass1);
testClass2.setTestClass4(testClass4);
testClass4.setTestClass3(testClass3);
TestClass2 testClass2a = createTestClass2(supplier);
testClass3.setTestClass2(testClass2a);
testClass2a.setTestClass4(createTestClass4(supplier));
testClass2a.setTestClass1(createTestClass1(supplier));
// when
long sum = objectUnderTest.sumIntegers(testClass2);
// then
int expectedSum = supplier.integers.stream().mapToInt(value -> value).sum();
Assertions.assertThat(sum).isEqualTo(expectedSum);
}
My objectUnderTest is:
private SumObjectGraph objectUnderTest = new SumObjectGraph();
Here is my ValueSupplier:
private static class ValueSupplier {
Random random = new Random();
List<Integer> integers = new ArrayList<>();
List<Float> floats = new ArrayList<>();
List<String> strings = new ArrayList<>();
int nextInt() {
int nextInt = random.nextInt(100);
integers.add(nextInt);
return nextInt;
}
float nextFloat() {
float nextFloat = random.nextFloat();
floats.add(nextFloat);
return nextFloat;
}
String nextString() {
String nextString = UUID.randomUUID().toString();
strings.add(nextString);
return nextString;
}
}
And my TestClasses:
private TestClass1 createTestClass1(ValueSupplier supplier) {
TestClass1 testClass1 = new TestClass1();
testClass1.setField1(supplier.nextInt());
testClass1.setField2(supplier.nextInt());
testClass1.setField3((long) supplier.nextInt());
testClass1.setField4(supplier.nextString());
testClass1.setField5((double) supplier.nextFloat());
testClass1.setField6(supplier.nextFloat());
testClass1.setField7(new StringBuilder(supplier.nextString()));
testClass1.setField8(supplier.nextInt());
return testClass1;
}
private TestClass2 createTestClass2(ValueSupplier supplier) {
TestClass2 testClass2 = new TestClass2();
testClass2.setField1(new StringBuilder(supplier.nextString()));
testClass2.setField2(supplier.nextInt());
testClass2.setField3((long) supplier.nextInt());
testClass2.setField4(supplier.nextString());
testClass2.setField5((double) supplier.nextFloat());
testClass2.setField6(supplier.nextFloat());
return testClass2;
}
private TestClass3 createTestClass3(ValueSupplier supplier) {
TestClass3 testClass3 = new TestClass3();
testClass3.setField1(supplier.nextInt());
testClass3.setField2(supplier.nextInt());
testClass3.setField3((long) supplier.nextInt());
testClass3.setField4(supplier.nextString());
testClass3.setField5(new StringBuilder(supplier.nextString()));
testClass3.setField6(supplier.nextInt());
return testClass3;
}
private TestClass4 createTestClass4(ValueSupplier supplier) {
TestClass4 testClass4 = new TestClass4();
testClass4.setField1(supplier.nextInt());
testClass4.setField2(supplier.nextInt());
testClass4.setField3(new StringBuilder(supplier.nextString()));
testClass4.setField4(supplier.nextInt());
testClass4.setField5((double) supplier.nextFloat());
testClass4.setField6(supplier.nextFloat());
return testClass4;
}
In order to fulfill this test, I need to implement my SumObjectGraph sumIntegers() method. To do it, i need to use reflection, to see if the current attribute is Long/Integer and sum them up.
The problem I'm getting is that an attribute, could be another class.
So I Thought of using recusivity, to check if the attribute is another class, then loop through its fields.
I got the following attempt:
public long sumIntegers(Object root) {
return recursivelySum(root, 0L);
}
public static Long recursivelySum(Object ob, Long sum){
for(Field attribute : ob.getClass().getDeclaredFields()){
if(TestClass1.class.isAssignableFrom(attribute.getType()) ||
TestClass2.class.isAssignableFrom(attribute.getType()) ||
TestClass3.class.isAssignableFrom(attribute.getType()) ||
TestClass4.class.isAssignableFrom(attribute.getType())){
return recursivelySum(getFields(attribute), sum);
} else {
sum += verifyAndSum(attribute, ob);
}
}
return sum;
}
public static Field [] getFields(Object ob) {
return ob.getClass().getDeclaredFields();
}
public static Long verifyAndSum(Field attribute, Object ob){
Number tmp = 0;
Long value = 0L;
if(long.class.isAssignableFrom(attribute.getType()) ||
int.class.isAssignableFrom(attribute.getType()) ||
Long.class.isAssignableFrom(attribute.getType()) ||
Integer.class.isAssignableFrom(attribute.getType())){
try {
attribute.setAccessible(true);
tmp = (Number) attribute.get(ob);
value += tmp.longValue();
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
return value;
}
But it's not quite working. The sum is not what excpected.
Aucun commentaire:
Enregistrer un commentaire