Skip to content

Commit f079468

Browse files
committed
feat: return result-object from instantiators
The result contains the outcome of the attempt to instantiate the class. Previously, only null was returned if the attempt failed; now the error message is being included.
1 parent 87937b3 commit f079468

File tree

8 files changed

+90
-44
lines changed

8 files changed

+90
-44
lines changed

src/main/java/com/github/nylle/javafixture/instantiation/BuilderInstantiator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static <T> BuilderInstantiator<T> create(Method builderMethodCandidate, S
3030
.orElse(null);
3131
}
3232

33-
public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) {
33+
public Result<T> invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) {
3434
try {
3535
var builder = builderMethod.invoke(null, new Object[]{});
3636

@@ -42,9 +42,9 @@ public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizat
4242
});
4343
}
4444

45-
return (T) buildMethod.invoke(builder, new Object[]{});
45+
return Result.of((T) buildMethod.invoke(builder, new Object[]{}));
4646
} catch (InvocationTargetException | IllegalAccessException ex) {
47-
return null;
47+
return Result.empty(ex.getMessage());
4848
}
4949
}
5050

src/main/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiator.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.github.nylle.javafixture.SpecimenType;
66

77
import java.lang.annotation.Annotation;
8+
import java.lang.reflect.InvocationTargetException;
89
import java.lang.reflect.Parameter;
910
import java.util.List;
1011
import java.util.Map;
@@ -23,13 +24,15 @@ public static <T> ConstructorInstantiator<T> create(java.lang.reflect.Constructo
2324
return new ConstructorInstantiator<>(constructor);
2425
}
2526

26-
public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) {
27+
public Result<T> invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) {
2728
try {
28-
return constructor.newInstance(stream(constructor.getParameters())
29+
return Result.of(constructor.newInstance(stream(constructor.getParameters())
2930
.map(p -> createParameter(p, specimenFactory, customizationContext))
30-
.toArray());
31-
} catch(Exception ex) {
32-
return null;
31+
.toArray()));
32+
} catch (InvocationTargetException ex) {
33+
return Result.empty(ex.getTargetException().getMessage());
34+
} catch (Exception ex) {
35+
return Result.empty(ex.getMessage());
3336
}
3437
}
3538

src/main/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiator.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,18 @@ public static <T> FactoryMethodInstantiator<T> create(Method factoryMethod, Spec
2323
return new FactoryMethodInstantiator<>(factoryMethod, targetType);
2424
}
2525

26-
public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) {
26+
public Result<T> invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) {
2727
try {
2828
List<Object> arguments = new ArrayList<>();
2929
for (int i = 0; i < factoryMethod.getParameterCount(); i++) {
30-
var genericParameterType = factoryMethod.getGenericParameterTypes()[i];
3130
var specimen = specimenFactory.build(targetType.isParameterized()
3231
? targetType.getGenericTypeArgument(i)
33-
: SpecimenType.fromClass(genericParameterType));
34-
var o = specimen.create(customizationContext, new Annotation[0]);
35-
arguments.add(o);
32+
: SpecimenType.fromClass(factoryMethod.getGenericParameterTypes()[i]));
33+
arguments.add(specimen.create(customizationContext, new Annotation[0]));
3634
}
37-
return (T) factoryMethod.invoke(null, arguments.toArray());
35+
return Result.of((T) factoryMethod.invoke(null, arguments.toArray()));
3836
} catch (Exception ex) {
39-
return null;
37+
return Result.empty(ex.getMessage());
4038
}
4139
}
4240
}

src/main/java/com/github/nylle/javafixture/instantiation/Instantiator.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,42 @@
55

66
public interface Instantiator<T> {
77

8-
T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext);
8+
Result<T> invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext);
99

10+
class Result<T> {
11+
private T value;
12+
private String message;
13+
14+
private Result(T value, String message) {
15+
this.value = value;
16+
this.message = message;
17+
}
18+
19+
public static <T> Result<T> of(T value) {
20+
if(value == null) {
21+
return new Result<T>(null, "result was null");
22+
}
23+
return new Result<T>(value, null);
24+
}
25+
26+
public static <T> Result<T> empty(String message) {
27+
return new Result<T>(null, message);
28+
}
29+
30+
public T getValue() {
31+
return value;
32+
}
33+
34+
public String getMessage() {
35+
return message;
36+
}
37+
38+
public boolean isPresent() {
39+
return value != null;
40+
}
41+
42+
public boolean isEmpty() {
43+
return value == null;
44+
}
45+
}
1046
}

src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.github.nylle.javafixture.annotations.testcases.TestCase;
44
import com.github.nylle.javafixture.annotations.testcases.TestWithCases;
5+
import com.github.nylle.javafixture.instantiation.BuilderInstantiator;
56
import com.github.nylle.javafixture.testobjects.ClassWithBuilder;
67
import com.github.nylle.javafixture.testobjects.ITestGeneric;
78
import com.github.nylle.javafixture.testobjects.TestAbstractClass;
@@ -59,7 +60,6 @@
5960
import java.util.concurrent.LinkedTransferQueue;
6061
import java.util.concurrent.TransferQueue;
6162

62-
import static com.github.nylle.javafixture.CustomizationContext.noContext;
6363
import static org.assertj.core.api.Assertions.assertThat;
6464
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
6565

@@ -375,14 +375,12 @@ class FindBuilders {
375375

376376
@Test
377377
void returnsListOfBuilders() {
378-
var specimenFactory = new SpecimenFactory(new Context(new Configuration()));
379-
380378
var sut = new SpecimenType<ClassWithBuilder>(){};
381379

382380
var actual = sut.findBuilders();
383381

384382
assertThat(actual).hasSize(1);
385-
assertThat(actual.get(0).invoke(specimenFactory, noContext())).isInstanceOf(ClassWithBuilder.class);
383+
assertThat(actual.get(0)).isInstanceOf(BuilderInstantiator.class);
386384
}
387385

388386
@TestWithCases

src/test/java/com/github/nylle/javafixture/instantiation/BuilderInstantiatorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ void invokeReturnsBuiltObjectWithAllMethodsCalled() throws NoSuchMethodException
1818

1919
var result = sut.invoke(new SpecimenFactory(new Context(new Configuration())), CustomizationContext.noContext());
2020

21-
assertThat(result).isInstanceOf(ClassWithBuilder.class);
21+
assertThat(result.getValue()).isInstanceOf(ClassWithBuilder.class);
2222

23-
var actual = (ClassWithBuilder) result;
23+
var actual = (ClassWithBuilder) result.getValue();
2424

2525
assertThat(actual.getNumber()).isNotNull();
2626
assertThat(actual.getString()).isNotNull();

src/test/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiatorTest.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.github.nylle.javafixture.CustomizationContext;
66
import com.github.nylle.javafixture.SpecimenFactory;
77
import com.github.nylle.javafixture.testobjects.TestObject;
8+
import com.github.nylle.javafixture.testobjects.withconstructor.ConstructorExceptionAndNoFactoryMethod;
89
import com.github.nylle.javafixture.testobjects.withconstructor.TestObjectWithConstructedField;
910
import com.github.nylle.javafixture.testobjects.withconstructor.TestObjectWithGenericConstructor;
1011
import org.junit.jupiter.api.DisplayName;
@@ -25,9 +26,9 @@ void canCreateInstanceFromConstructor() throws NoSuchMethodException {
2526

2627
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), false));
2728

28-
assertThat(actual).isInstanceOf(TestObjectWithGenericConstructor.class);
29-
assertThat(actual.getValue()).isInstanceOf(String.class);
30-
assertThat(actual.getInteger()).isInstanceOf(Optional.class);
29+
assertThat(actual.getValue()).isInstanceOf(TestObjectWithGenericConstructor.class);
30+
assertThat(actual.getValue().getValue()).isInstanceOf(String.class);
31+
assertThat(actual.getValue().getInteger()).isInstanceOf(Optional.class);
3132
}
3233

3334
@Test
@@ -37,8 +38,8 @@ void fieldsNotSetByConstructorAreNull() throws NoSuchMethodException {
3738

3839
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), false));
3940

40-
assertThat(actual).isInstanceOf(TestObjectWithGenericConstructor.class);
41-
assertThat(actual.getPrivateField()).isNull();
41+
assertThat(actual.getValue()).isInstanceOf(TestObjectWithGenericConstructor.class);
42+
assertThat(actual.getValue().getPrivateField()).isNull();
4243
}
4344

4445
@Test
@@ -49,7 +50,7 @@ void argumentsCanBeCustomized() throws NoSuchMethodException {
4950
// use arg0, because .class files do not store formal parameter names by default
5051
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of("arg0", "customized"), true));
5152

52-
assertThat(actual.getValue()).isEqualTo("customized");
53+
assertThat(actual.getValue().getValue()).isEqualTo("customized");
5354
}
5455

5556
@Test
@@ -59,9 +60,9 @@ void usingConstructorIsRecursive() throws NoSuchMethodException {
5960

6061
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), true));
6162

62-
assertThat(actual).isInstanceOf(TestObjectWithConstructedField.class);
63-
assertThat(actual.getTestObjectWithGenericConstructor().getPrivateField()).isNull();
64-
assertThat(actual.getNotSetByConstructor()).isNull();
63+
assertThat(actual.getValue()).isInstanceOf(TestObjectWithConstructedField.class);
64+
assertThat(actual.getValue().getTestObjectWithGenericConstructor().getPrivateField()).isNull();
65+
assertThat(actual.getValue().getNotSetByConstructor()).isNull();
6566
}
6667

6768
@Test
@@ -72,7 +73,7 @@ void constructorArgumentsAreUsedOnce() throws NoSuchMethodException {
7273
// use arg0, because .class files do not store formal parameter names by default
7374
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of("arg0", 2), true));
7475

75-
assertThat(actual.getSetByConstructor()).isEqualTo(2);
76+
assertThat(actual.getValue().getSetByConstructor()).isEqualTo(2);
7677
}
7778

7879
@Test
@@ -83,6 +84,16 @@ void ignoredConstructorArgsAreRespected() throws NoSuchMethodException {
8384
// use arg0, because .class files do not store formal parameter names by default
8485
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of("arg0"), Map.of(), true));
8586

86-
assertThat(actual.getSetByConstructor()).isEqualTo(0);
87+
assertThat(actual.getValue().getSetByConstructor()).isEqualTo(0);
88+
}
89+
90+
@Test
91+
void xxx() throws NoSuchMethodException {
92+
var sut = ConstructorInstantiator.create(ConstructorExceptionAndNoFactoryMethod.class.getConstructor());
93+
94+
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), true));
95+
96+
assertThat(actual.isEmpty()).isTrue();
97+
assertThat(actual.getMessage()).isEqualTo("expected for tests");
8798
}
8899
}

src/test/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiatorTest.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void factoryMethodWithoutArgument() throws NoSuchMethodException {
2727

2828
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
2929

30-
assertThat(actual.getValue()).isEqualTo(42);
30+
assertThat(actual.getValue().getValue()).isEqualTo(42);
3131
}
3232

3333
@Test
@@ -37,7 +37,7 @@ void returnsInstanceOfClassUsingFactoryMethodWithArguments() throws NoSuchMethod
3737

3838
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
3939

40-
assertThat(actual.getValue()).isNotNull();
40+
assertThat(actual.getValue().getValue()).isNotNull();
4141
}
4242

4343
@Test
@@ -47,7 +47,7 @@ void factoryMethodWithGenericArgument() throws NoSuchMethodException {
4747

4848
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
4949

50-
assertThat(actual.getValue()).isNotNull();
50+
assertThat(actual.getValue().getValue()).isNotNull();
5151
}
5252

5353
@Test
@@ -57,7 +57,7 @@ void returnsInstanceOfAbstractClassUsingFactoryMethod() throws NoSuchMethodExcep
5757

5858
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
5959

60-
assertThat(actual).isInstanceOf(Charset.class);
60+
assertThat(actual.getValue()).isInstanceOf(Charset.class);
6161
}
6262

6363
@Test
@@ -67,9 +67,9 @@ void createOptionalWithArgument() throws NoSuchMethodException {
6767

6868
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
6969

70-
assertThat(actual).isInstanceOf(Optional.class);
71-
assertThat(actual).isNotEmpty();
72-
assertThat(actual.get()).isInstanceOf(String.class);
70+
assertThat(actual.getValue()).isInstanceOf(Optional.class);
71+
assertThat(actual.getValue()).isNotEmpty();
72+
assertThat(actual.getValue().get()).isInstanceOf(String.class);
7373
}
7474

7575
@Test
@@ -79,8 +79,8 @@ void createOptionalWithoutArgument() throws NoSuchMethodException {
7979

8080
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
8181

82-
assertThat(actual).isInstanceOf(Optional.class);
83-
assertThat(actual).isEmpty();
82+
assertThat(actual.getValue()).isInstanceOf(Optional.class);
83+
assertThat(actual.getValue()).isEmpty();
8484
}
8585

8686
@Test
@@ -90,7 +90,7 @@ void genericNoArgumentFactoryMethod() throws NoSuchMethodException {
9090

9191
var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext());
9292

93-
assertThat(actual).isNotNull();
94-
assertThat(actual.getValue()).isEqualTo(42);
93+
assertThat(actual.getValue()).isNotNull();
94+
assertThat(actual.getValue().getValue()).isEqualTo(42);
9595
}
9696
}

0 commit comments

Comments
 (0)