diff --git a/src/main/java/com/github/nylle/javafixture/instantiation/BuilderInstantiator.java b/src/main/java/com/github/nylle/javafixture/instantiation/BuilderInstantiator.java index 111142b..2679fdf 100644 --- a/src/main/java/com/github/nylle/javafixture/instantiation/BuilderInstantiator.java +++ b/src/main/java/com/github/nylle/javafixture/instantiation/BuilderInstantiator.java @@ -30,7 +30,7 @@ public static BuilderInstantiator create(Method builderMethodCandidate, S .orElse(null); } - public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) { + public Result invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) { try { var builder = builderMethod.invoke(null, new Object[]{}); @@ -42,9 +42,9 @@ public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizat }); } - return (T) buildMethod.invoke(builder, new Object[]{}); + return Result.of((T) buildMethod.invoke(builder, new Object[]{})); } catch (InvocationTargetException | IllegalAccessException ex) { - return null; + return Result.empty(ex.getMessage()); } } diff --git a/src/main/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiator.java b/src/main/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiator.java index 943bd02..6e513b0 100644 --- a/src/main/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiator.java +++ b/src/main/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiator.java @@ -5,6 +5,7 @@ import com.github.nylle.javafixture.SpecimenType; import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Parameter; import java.util.List; import java.util.Map; @@ -23,13 +24,15 @@ public static ConstructorInstantiator create(java.lang.reflect.Constructo return new ConstructorInstantiator<>(constructor); } - public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) { + public Result invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) { try { - return constructor.newInstance(stream(constructor.getParameters()) + return Result.of(constructor.newInstance(stream(constructor.getParameters()) .map(p -> createParameter(p, specimenFactory, customizationContext)) - .toArray()); - } catch(Exception ex) { - return null; + .toArray())); + } catch (InvocationTargetException ex) { + return Result.empty(ex.getTargetException().getMessage()); + } catch (Exception ex) { + return Result.empty(ex.getMessage()); } } diff --git a/src/main/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiator.java b/src/main/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiator.java index 69899e3..4f823db 100644 --- a/src/main/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiator.java +++ b/src/main/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiator.java @@ -23,20 +23,18 @@ public static FactoryMethodInstantiator create(Method factoryMethod, Spec return new FactoryMethodInstantiator<>(factoryMethod, targetType); } - public T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) { + public Result invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext) { try { List arguments = new ArrayList<>(); for (int i = 0; i < factoryMethod.getParameterCount(); i++) { - var genericParameterType = factoryMethod.getGenericParameterTypes()[i]; var specimen = specimenFactory.build(targetType.isParameterized() ? targetType.getGenericTypeArgument(i) - : SpecimenType.fromClass(genericParameterType)); - var o = specimen.create(customizationContext, new Annotation[0]); - arguments.add(o); + : SpecimenType.fromClass(factoryMethod.getGenericParameterTypes()[i])); + arguments.add(specimen.create(customizationContext, new Annotation[0])); } - return (T) factoryMethod.invoke(null, arguments.toArray()); + return Result.of((T) factoryMethod.invoke(null, arguments.toArray())); } catch (Exception ex) { - return null; + return Result.empty(ex.getMessage()); } } } diff --git a/src/main/java/com/github/nylle/javafixture/instantiation/Instantiator.java b/src/main/java/com/github/nylle/javafixture/instantiation/Instantiator.java index f116b37..d2bfe76 100644 --- a/src/main/java/com/github/nylle/javafixture/instantiation/Instantiator.java +++ b/src/main/java/com/github/nylle/javafixture/instantiation/Instantiator.java @@ -5,6 +5,42 @@ public interface Instantiator { - T invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext); + Result invoke(SpecimenFactory specimenFactory, CustomizationContext customizationContext); + class Result { + private T value; + private String message; + + private Result(T value, String message) { + this.value = value; + this.message = message; + } + + public static Result of(T value) { + if(value == null) { + return new Result(null, "result was null"); + } + return new Result(value, null); + } + + public static Result empty(String message) { + return new Result(null, message); + } + + public T getValue() { + return value; + } + + public String getMessage() { + return message; + } + + public boolean isPresent() { + return value != null; + } + + public boolean isEmpty() { + return value == null; + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java b/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java index ed1c497..6b09ba1 100644 --- a/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java +++ b/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java @@ -2,6 +2,7 @@ import com.github.nylle.javafixture.annotations.testcases.TestCase; import com.github.nylle.javafixture.annotations.testcases.TestWithCases; +import com.github.nylle.javafixture.instantiation.BuilderInstantiator; import com.github.nylle.javafixture.testobjects.ClassWithBuilder; import com.github.nylle.javafixture.testobjects.ITestGeneric; import com.github.nylle.javafixture.testobjects.TestAbstractClass; @@ -59,7 +60,6 @@ import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.TransferQueue; -import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -375,14 +375,12 @@ class FindBuilders { @Test void returnsListOfBuilders() { - var specimenFactory = new SpecimenFactory(new Context(new Configuration())); - var sut = new SpecimenType(){}; var actual = sut.findBuilders(); assertThat(actual).hasSize(1); - assertThat(actual.get(0).invoke(specimenFactory, noContext())).isInstanceOf(ClassWithBuilder.class); + assertThat(actual.get(0)).isInstanceOf(BuilderInstantiator.class); } @TestWithCases diff --git a/src/test/java/com/github/nylle/javafixture/instantiation/BuilderInstantiatorTest.java b/src/test/java/com/github/nylle/javafixture/instantiation/BuilderInstantiatorTest.java index 5472fa3..66334d3 100644 --- a/src/test/java/com/github/nylle/javafixture/instantiation/BuilderInstantiatorTest.java +++ b/src/test/java/com/github/nylle/javafixture/instantiation/BuilderInstantiatorTest.java @@ -18,9 +18,9 @@ void invokeReturnsBuiltObjectWithAllMethodsCalled() throws NoSuchMethodException var result = sut.invoke(new SpecimenFactory(new Context(new Configuration())), CustomizationContext.noContext()); - assertThat(result).isInstanceOf(ClassWithBuilder.class); + assertThat(result.getValue()).isInstanceOf(ClassWithBuilder.class); - var actual = (ClassWithBuilder) result; + var actual = (ClassWithBuilder) result.getValue(); assertThat(actual.getNumber()).isNotNull(); assertThat(actual.getString()).isNotNull(); diff --git a/src/test/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiatorTest.java b/src/test/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiatorTest.java index 159211c..6e44c33 100644 --- a/src/test/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiatorTest.java +++ b/src/test/java/com/github/nylle/javafixture/instantiation/ConstructorInstantiatorTest.java @@ -5,6 +5,7 @@ import com.github.nylle.javafixture.CustomizationContext; import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.testobjects.TestObject; +import com.github.nylle.javafixture.testobjects.withconstructor.ConstructorExceptionAndNoFactoryMethod; import com.github.nylle.javafixture.testobjects.withconstructor.TestObjectWithConstructedField; import com.github.nylle.javafixture.testobjects.withconstructor.TestObjectWithGenericConstructor; import org.junit.jupiter.api.DisplayName; @@ -25,9 +26,9 @@ void canCreateInstanceFromConstructor() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), false)); - assertThat(actual).isInstanceOf(TestObjectWithGenericConstructor.class); - assertThat(actual.getValue()).isInstanceOf(String.class); - assertThat(actual.getInteger()).isInstanceOf(Optional.class); + assertThat(actual.getValue()).isInstanceOf(TestObjectWithGenericConstructor.class); + assertThat(actual.getValue().getValue()).isInstanceOf(String.class); + assertThat(actual.getValue().getInteger()).isInstanceOf(Optional.class); } @Test @@ -37,8 +38,8 @@ void fieldsNotSetByConstructorAreNull() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), false)); - assertThat(actual).isInstanceOf(TestObjectWithGenericConstructor.class); - assertThat(actual.getPrivateField()).isNull(); + assertThat(actual.getValue()).isInstanceOf(TestObjectWithGenericConstructor.class); + assertThat(actual.getValue().getPrivateField()).isNull(); } @Test @@ -49,7 +50,7 @@ void argumentsCanBeCustomized() throws NoSuchMethodException { // use arg0, because .class files do not store formal parameter names by default var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of("arg0", "customized"), true)); - assertThat(actual.getValue()).isEqualTo("customized"); + assertThat(actual.getValue().getValue()).isEqualTo("customized"); } @Test @@ -59,9 +60,9 @@ void usingConstructorIsRecursive() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), true)); - assertThat(actual).isInstanceOf(TestObjectWithConstructedField.class); - assertThat(actual.getTestObjectWithGenericConstructor().getPrivateField()).isNull(); - assertThat(actual.getNotSetByConstructor()).isNull(); + assertThat(actual.getValue()).isInstanceOf(TestObjectWithConstructedField.class); + assertThat(actual.getValue().getTestObjectWithGenericConstructor().getPrivateField()).isNull(); + assertThat(actual.getValue().getNotSetByConstructor()).isNull(); } @Test @@ -72,7 +73,7 @@ void constructorArgumentsAreUsedOnce() throws NoSuchMethodException { // use arg0, because .class files do not store formal parameter names by default var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of("arg0", 2), true)); - assertThat(actual.getSetByConstructor()).isEqualTo(2); + assertThat(actual.getValue().getSetByConstructor()).isEqualTo(2); } @Test @@ -83,6 +84,16 @@ void ignoredConstructorArgsAreRespected() throws NoSuchMethodException { // use arg0, because .class files do not store formal parameter names by default var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of("arg0"), Map.of(), true)); - assertThat(actual.getSetByConstructor()).isEqualTo(0); + assertThat(actual.getValue().getSetByConstructor()).isEqualTo(0); + } + + @Test + void xxx() throws NoSuchMethodException { + var sut = ConstructorInstantiator.create(ConstructorExceptionAndNoFactoryMethod.class.getConstructor()); + + var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), new CustomizationContext(List.of(), Map.of(), true)); + + assertThat(actual.isEmpty()).isTrue(); + assertThat(actual.getMessage()).isEqualTo("expected for tests"); } } diff --git a/src/test/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiatorTest.java b/src/test/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiatorTest.java index 267a716..5ec2139 100644 --- a/src/test/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiatorTest.java +++ b/src/test/java/com/github/nylle/javafixture/instantiation/FactoryMethodInstantiatorTest.java @@ -27,7 +27,7 @@ void factoryMethodWithoutArgument() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual.getValue()).isEqualTo(42); + assertThat(actual.getValue().getValue()).isEqualTo(42); } @Test @@ -37,7 +37,7 @@ void returnsInstanceOfClassUsingFactoryMethodWithArguments() throws NoSuchMethod var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual.getValue()).isNotNull(); + assertThat(actual.getValue().getValue()).isNotNull(); } @Test @@ -47,7 +47,7 @@ void factoryMethodWithGenericArgument() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual.getValue()).isNotNull(); + assertThat(actual.getValue().getValue()).isNotNull(); } @Test @@ -57,7 +57,7 @@ void returnsInstanceOfAbstractClassUsingFactoryMethod() throws NoSuchMethodExcep var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual).isInstanceOf(Charset.class); + assertThat(actual.getValue()).isInstanceOf(Charset.class); } @Test @@ -67,9 +67,9 @@ void createOptionalWithArgument() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual).isInstanceOf(Optional.class); - assertThat(actual).isNotEmpty(); - assertThat(actual.get()).isInstanceOf(String.class); + assertThat(actual.getValue()).isInstanceOf(Optional.class); + assertThat(actual.getValue()).isNotEmpty(); + assertThat(actual.getValue().get()).isInstanceOf(String.class); } @Test @@ -79,8 +79,8 @@ void createOptionalWithoutArgument() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual).isInstanceOf(Optional.class); - assertThat(actual).isEmpty(); + assertThat(actual.getValue()).isInstanceOf(Optional.class); + assertThat(actual.getValue()).isEmpty(); } @Test @@ -90,7 +90,7 @@ void genericNoArgumentFactoryMethod() throws NoSuchMethodException { var actual = sut.invoke(new SpecimenFactory(new Context(Configuration.configure())), noContext()); - assertThat(actual).isNotNull(); - assertThat(actual.getValue()).isEqualTo(42); + assertThat(actual.getValue()).isNotNull(); + assertThat(actual.getValue().getValue()).isEqualTo(42); } }