diff --git a/build.gradle b/build.gradle index a4bf25c4..62288dcf 100644 --- a/build.gradle +++ b/build.gradle @@ -93,6 +93,7 @@ dependencies { testCompile("org.junit.platform:junit-platform-runner:${JUNIT_PLATFORM_VERSION}") { changing = true } testCompile("org.assertj:assertj-core:${ASSERTJ_CORE_VERSION}") testCompile("org.mockito:mockito-core:${MOCKITO_VERSION}") + testCompile 'info.solidsoft.mockito:mockito-java8:2.2.0' testCompile("org.powermock.tests:powermock-tests-utils:${POWER_MOCK_UTILS_VERSION}") testCompileOnly("org.apiguardian:apiguardian-api:1.0.0") } diff --git a/src/main/java/pl/pojo/tester/api/assertion/AbstractAssertion.java b/src/main/java/pl/pojo/tester/api/assertion/AbstractAssertion.java index de87273d..6640d6f1 100644 --- a/src/main/java/pl/pojo/tester/api/assertion/AbstractAssertion.java +++ b/src/main/java/pl/pojo/tester/api/assertion/AbstractAssertion.java @@ -1,20 +1,24 @@ package pl.pojo.tester.api.assertion; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.slf4j.Logger; import pl.pojo.tester.api.ClassAndFieldPredicatePair; import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; +import pl.pojo.tester.internal.instantiator.AbstractObjectInstantiator; +import pl.pojo.tester.internal.instantiator.SupplierInstantiator; +import pl.pojo.tester.internal.instantiator.UserDefinedConstructorInstantiator; +import pl.pojo.tester.internal.tester.AbstractTester; +import pl.pojo.tester.internal.utils.ClassLoader; import pl.pojo.tester.internal.utils.Permutator; import pl.pojo.tester.internal.utils.SublistFieldPermutator; import pl.pojo.tester.internal.utils.ThoroughFieldPermutator; -import pl.pojo.tester.internal.tester.AbstractTester; -import pl.pojo.tester.internal.utils.ClassLoader; import java.util.Arrays; import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import static pl.pojo.tester.internal.preconditions.ParameterPreconditions.checkNotBlank; @@ -40,7 +44,7 @@ public abstract class AbstractAssertion { .forEach(DEFAULT_TESTERS::add); } - private final MultiValuedMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); + private final List instantiators = new LinkedList<>(); Set testers = new HashSet<>(); private AbstractFieldValueChanger abstractFieldValueChanger; private Permutator permutator = new ThoroughFieldPermutator(); @@ -124,7 +128,7 @@ public void areWellImplemented() { } testers.forEach(tester -> tester.setPermutator(permutator)); - testers.forEach(tester -> tester.setUserDefinedConstructors(constructorParameters)); + testers.forEach(tester -> tester.setUserDefinedInstantiators(instantiators)); runAssertions(); } @@ -164,8 +168,8 @@ public AbstractAssertion create(final String qualifiedClassName, checkNotNull("constructorParameters", constructorParameters); final Class clazz = ClassLoader.loadClass(qualifiedClassName); - this.constructorParameters.put(clazz, constructorParameters); - return this; + + return create(clazz, constructorParameters); } /** @@ -202,7 +206,39 @@ public AbstractAssertion create(final Class clazz, final ConstructorParameter checkNotNull("clazz", clazz); checkNotNull("constructorParameters", constructorParameters); - this.constructorParameters.put(clazz, constructorParameters); + final UserDefinedConstructorInstantiator instantiator = new UserDefinedConstructorInstantiator(clazz, + constructorParameters); + return create(clazz, instantiator); + } + + /** + * Indicates, that class should be constructed using given instantiator. + * + * @param clazz class to instantiate + * @param instantiator instantiator which will create instance of given class + * @return itself + * @see ConstructorParameters + */ + public AbstractAssertion create(final Class clazz, final AbstractObjectInstantiator instantiator) { + checkNotNull("clazz", clazz); + checkNotNull("instantiator", instantiator); + + return create(clazz, instantiator::instantiate); + } + + /** + * Indicates, that class should be constructed using given supplier. + * + * @param clazz class to instantiate + * @param supplier supplier that will create given class + * @return itself + * @see ConstructorParameters + */ + public AbstractAssertion create(final Class clazz, final Supplier supplier) { + checkNotNull("clazz", clazz); + checkNotNull("supplier", supplier); + + this.instantiators.add(new SupplierInstantiator(clazz, supplier)); return this; } diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiator.java index 220e11be..917f2d5c 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiator.java @@ -1,66 +1,34 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import pl.pojo.tester.api.ConstructorParameters; -import pl.pojo.tester.internal.utils.CollectionUtils; import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.Collection; +import java.util.List; import java.util.Objects; -import java.util.stream.Stream; +import java.util.Optional; abstract class AbstractMultiConstructorInstantiator extends AbstractObjectInstantiator { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractMultiConstructorInstantiator.class); + private final List instantiators; - AbstractMultiConstructorInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); - } - - protected Object instantiateUsingUserParameters() { - final Collection userConstructorParameters = constructorParameters.get(clazz); - if (userDefinedOwnParametersForThisClass(userConstructorParameters)) { - final Object result = tryToInstantiateUsing(userConstructorParameters); - if (result != null) { - return result; - } - LOGGER.warn("Could not instantiate class {} with user defined parameters. " - + "Trying create instance finding best constructor", clazz); - } - return null; - } - - private boolean userDefinedOwnParametersForThisClass(final Collection userConstructorParameters) { - return CollectionUtils.isNotEmpty(userConstructorParameters); - } - - private Object tryToInstantiateUsing(final Collection userConstructorParameters) { - for (final ConstructorParameters param : userConstructorParameters) { - Class[] parameterTypes = param.getParametersTypes(); - try { - Object[] parameters = param.getParameters(); - if (isInnerClass()) { - parameterTypes = putEnclosingClassAsFirstParameterType(clazz.getEnclosingClass(), parameterTypes); - final Object enclosingClassInstance = instantiateEnclosingClass(); - parameters = putEnclosingClassInstanceAsFirstParameter(enclosingClassInstance, parameters); - } - return createObjectFromArgsConstructor(parameterTypes, parameters); - } catch (final ObjectInstantiationException e) { - LOGGER.debug("ObjectInstantiationException:", e); - // ignore, try all user defined constructor parameters and types - } - } - return null; + AbstractMultiConstructorInstantiator(final Class clazz, final List instantiators) { + super(clazz); + this.instantiators = instantiators; } protected Object createFindingBestConstructor() { + final Optional instantiator = instantiators.stream() + .filter(i -> clazz.equals(i.clazz)) + .findFirst(); + if (instantiator.isPresent()) { + return instantiator.get() + .instantiate(); + } final Constructor[] constructors = clazz.getDeclaredConstructors(); return Arrays.stream(constructors) .map(this::createObjectFromConstructor) @@ -75,28 +43,6 @@ protected Object createFindingBestConstructor() { protected abstract ObjectInstantiationException createObjectInstantiationException(); - private Object instantiateEnclosingClass() { - final Class enclosingClass = clazz.getEnclosingClass(); - return Instantiable.forClass(enclosingClass, constructorParameters) - .instantiate(); - } - - private Class[] putEnclosingClassAsFirstParameterType(final Class enclosingClass, - final Class[] constructorParametersTypes) { - return Stream.concat(Stream.of(enclosingClass), Arrays.stream(constructorParametersTypes)) - .toArray(Class[]::new); - } - - private boolean isInnerClass() { - return clazz.getEnclosingClass() != null && !Modifier.isStatic(clazz.getModifiers()); - } - - private Object[] putEnclosingClassInstanceAsFirstParameter(final Object enclosingClassInstance, - final Object[] arguments) { - return Stream.concat(Stream.of(enclosingClassInstance), Arrays.stream(arguments)) - .toArray(Object[]::new); - } - private Object createObjectFromConstructor(final Constructor constructor) { makeAccessible(constructor); if (constructor.getParameterCount() == 0) { @@ -104,7 +50,7 @@ private Object createObjectFromConstructor(final Constructor constructor) { } else { try { final Object[] parameters = Instantiable.instantiateClasses(constructor.getParameterTypes(), - constructorParameters); + instantiators); return createObjectFromArgsConstructor(constructor.getParameterTypes(), parameters); } catch (final Exception e) { LOGGER.debug("Exception:", e); diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/AbstractObjectInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/AbstractObjectInstantiator.java index 18964897..ad5440ba 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/AbstractObjectInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/AbstractObjectInstantiator.java @@ -1,17 +1,11 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - -abstract class AbstractObjectInstantiator { +public abstract class AbstractObjectInstantiator { protected final Class clazz; - protected final MultiValuedMap, ConstructorParameters> constructorParameters; - AbstractObjectInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { + AbstractObjectInstantiator(final Class clazz) { this.clazz = clazz; - this.constructorParameters = constructorParameters; } public abstract Object instantiate(); diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/ArrayInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/ArrayInstantiator.java index 9465e99d..a9bd6750 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/ArrayInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/ArrayInstantiator.java @@ -1,17 +1,13 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - import java.lang.reflect.Array; class ArrayInstantiator extends AbstractObjectInstantiator { private static final int DEFAULT_ARRAY_LENGTH = 0; - ArrayInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + ArrayInstantiator(final Class clazz) { + super(clazz); } @Override diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiator.java index 142d63e1..f104e1c6 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiator.java @@ -1,30 +1,24 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import pl.pojo.tester.api.ConstructorParameters; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.List; class BestConstructorInstantiator extends AbstractMultiConstructorInstantiator { private static final Logger LOGGER = LoggerFactory.getLogger(BestConstructorInstantiator.class); - BestConstructorInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + BestConstructorInstantiator(final Class clazz, final List instantiators) { + super(clazz, instantiators); } @Override public Object instantiate() { - Object result = instantiateUsingUserParameters(); - if (result == null) { - result = createFindingBestConstructor(); - } - return result; + return createFindingBestConstructor(); } @Override diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/CollectionInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/CollectionInstantiator.java index d1b2c026..a66310e6 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/CollectionInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/CollectionInstantiator.java @@ -1,9 +1,6 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - import java.util.ArrayList; import java.util.Collection; import java.util.Deque; @@ -58,9 +55,8 @@ class CollectionInstantiator extends AbstractObjectInstantiator { PREPARED_OBJECTS.put(Iterable.class, new ArrayList<>()); } - CollectionInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + CollectionInstantiator(final Class clazz) { + super(clazz); } @Override diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiator.java index 0042159f..aaca46d4 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiator.java @@ -1,9 +1,6 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; @@ -11,9 +8,8 @@ class DefaultConstructorInstantiator extends AbstractObjectInstantiator { - DefaultConstructorInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + DefaultConstructorInstantiator(final Class clazz) { + super(clazz); } @Override diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/EnumInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/EnumInstantiator.java index f17563b2..1d6aa908 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/EnumInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/EnumInstantiator.java @@ -1,16 +1,12 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - import java.util.Random; class EnumInstantiator extends AbstractObjectInstantiator { - EnumInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + EnumInstantiator(final Class clazz) { + super(clazz); } @Override diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/Instantiable.java b/src/main/java/pl/pojo/tester/internal/instantiator/Instantiable.java index 8049da92..ff0dbc86 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/Instantiable.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/Instantiable.java @@ -1,14 +1,11 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - -import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Optional; public final class Instantiable { @@ -16,7 +13,6 @@ public final class Instantiable { static { INSTANTIATORS = new LinkedList<>(); - INSTANTIATORS.add(UserDefinedConstructorInstantiator.class); INSTANTIATORS.add(JavaTypeInstantiator.class); INSTANTIATORS.add(CollectionInstantiator.class); INSTANTIATORS.add(DefaultConstructorInstantiator.class); @@ -30,38 +26,37 @@ private Instantiable() { } static Object[] instantiateClasses(final Class[] classes, - final MultiValuedMap, ConstructorParameters> constructorParameters) { + final List predefinedInstantiators) { return Arrays.stream(classes) - .map(clazz -> Instantiable.forClass(clazz, constructorParameters)) + .map(clazz -> Instantiable.forClass(clazz, predefinedInstantiators)) .map(AbstractObjectInstantiator::instantiate) .toArray(); } static AbstractObjectInstantiator forClass(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - return instantiateInstantiators(clazz, constructorParameters).stream() - .filter(AbstractObjectInstantiator::canInstantiate) - .findAny() - .get(); + final List predefinedInstantiators) { + final Optional userDefined = predefinedInstantiators.stream() + .filter(instantiator -> clazz.equals( + instantiator.clazz)) + .findFirst(); + return userDefined.orElseGet(() -> instantiateInstantiators(clazz, predefinedInstantiators).stream() + .filter(AbstractObjectInstantiator::canInstantiate) + .findFirst() + .get()); } private static List instantiateInstantiators(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { + final List predefinedInstantiators) { final List instantiators = new ArrayList<>(); - try { - for (final Class instantiator : INSTANTIATORS) { - final Constructor constructor = - instantiator.getDeclaredConstructor(Class.class, MultiValuedMap.class); - constructor.setAccessible(true); - final AbstractObjectInstantiator abstractObjectInstantiator = constructor.newInstance(clazz, - constructorParameters); - instantiators.add(abstractObjectInstantiator); - } - } catch (final Exception e) { - throw new RuntimeException("Cannot load instantiators form pl.pojo.tester.internal.instantiator package.", - e); - } + + instantiators.add(new JavaTypeInstantiator(clazz)); + instantiators.add(new CollectionInstantiator(clazz)); + instantiators.add(new DefaultConstructorInstantiator(clazz)); + instantiators.add(new EnumInstantiator(clazz)); + instantiators.add(new ArrayInstantiator(clazz)); + instantiators.add(new ProxyInstantiator(clazz, predefinedInstantiators)); + instantiators.add(new BestConstructorInstantiator(clazz, predefinedInstantiators)); + return instantiators; } - } diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiator.java index fa40e318..c9385e8f 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiator.java @@ -1,9 +1,6 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; -import pl.pojo.tester.api.ConstructorParameters; - import java.math.BigDecimal; import java.math.BigInteger; import java.time.Clock; @@ -76,9 +73,8 @@ class JavaTypeInstantiator extends AbstractObjectInstantiator { preparedObjects.put(ZoneOffset.class.getName(), ZoneOffset.UTC); } - JavaTypeInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + JavaTypeInstantiator(final Class clazz) { + super(clazz); } @Override diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/ObjectGenerator.java b/src/main/java/pl/pojo/tester/internal/instantiator/ObjectGenerator.java index d3b1dab2..82ea6543 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/ObjectGenerator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/ObjectGenerator.java @@ -1,11 +1,9 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.pojo.tester.api.ClassAndFieldPredicatePair; -import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import pl.pojo.tester.internal.utils.FieldUtils; import pl.pojo.tester.internal.utils.Permutator; @@ -27,19 +25,19 @@ public class ObjectGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(ObjectGenerator.class); private final AbstractFieldValueChanger abstractFieldValueChanger; - private final MultiValuedMap, ConstructorParameters> constructorParameters; + private final List additionalInstantiators; private final Permutator permutator; public ObjectGenerator(final AbstractFieldValueChanger abstractFieldValueChanger, - final MultiValuedMap, ConstructorParameters> constructorParameters, + final List additionalInstantiators, final Permutator permutator) { this.abstractFieldValueChanger = abstractFieldValueChanger; - this.constructorParameters = constructorParameters; + this.additionalInstantiators = additionalInstantiators; this.permutator = permutator; } public Object createNewInstance(final Class clazz) { - return Instantiable.forClass(clazz, constructorParameters) + return Instantiable.forClass(clazz, additionalInstantiators) .instantiate(); } diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/ObjectInstantiatorAdapter.java b/src/main/java/pl/pojo/tester/internal/instantiator/ObjectInstantiatorAdapter.java new file mode 100644 index 00000000..beba53c4 --- /dev/null +++ b/src/main/java/pl/pojo/tester/internal/instantiator/ObjectInstantiatorAdapter.java @@ -0,0 +1,23 @@ +package pl.pojo.tester.internal.instantiator; + +public class ObjectInstantiatorAdapter extends AbstractObjectInstantiator { + + ObjectInstantiatorAdapter(final Class clazz) { + super(clazz); + } + + @Override + public Object instantiate() { + return null; + } + + @Override + public boolean canInstantiate() { + return true; + } + + @Override + public String toString() { + return "ObjectInstantiatorAdapter{clazz=" + clazz + '}'; + } +} diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/ProxyInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/ProxyInstantiator.java index bc215e1c..53188ec2 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/ProxyInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/ProxyInstantiator.java @@ -2,16 +2,15 @@ import javassist.util.proxy.ProxyFactory; -import org.apache.commons.collections4.MultiValuedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import pl.pojo.tester.api.ConstructorParameters; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import java.util.List; class ProxyInstantiator extends AbstractMultiConstructorInstantiator { @@ -20,22 +19,21 @@ class ProxyInstantiator extends AbstractMultiConstructorInstantiator { private final ProxyFactory proxyFactory = new ProxyFactory(); - ProxyInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + ProxyInstantiator(final Class clazz, final List instantiators) { + super(clazz, instantiators); } @Override public Object instantiate() { - Object result = instantiateUsingUserParameters(); - if (result == null) { - if (clazz.isAnnotation() || clazz.isInterface()) { - result = proxyByJava(); - } else { - proxyFactory.setSuperclass(clazz); - result = createFindingBestConstructor(); - } + final Object result; + + if (clazz.isAnnotation() || clazz.isInterface()) { + result = proxyByJava(); + } else { + proxyFactory.setSuperclass(clazz); + result = createFindingBestConstructor(); } + return result; } diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/SupplierInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/SupplierInstantiator.java new file mode 100644 index 00000000..4d4f3eb7 --- /dev/null +++ b/src/main/java/pl/pojo/tester/internal/instantiator/SupplierInstantiator.java @@ -0,0 +1,23 @@ +package pl.pojo.tester.internal.instantiator; + +import java.util.function.Supplier; + +public class SupplierInstantiator extends ObjectInstantiatorAdapter { + + private final Supplier supplier; + + public SupplierInstantiator(final Class clazz, final Supplier supplier) { + super(clazz); + this.supplier = supplier; + } + + @Override + public Object instantiate() { + return supplier.get(); + } + + @Override + public String toString() { + return "SupplierInstantiator{supplier=" + supplier + ", clazz=" + clazz + '}'; + } +} diff --git a/src/main/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiator.java b/src/main/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiator.java index 00657d72..e1f891a4 100644 --- a/src/main/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiator.java +++ b/src/main/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiator.java @@ -1,6 +1,5 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.MultiValuedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.pojo.tester.api.ConstructorParameters; @@ -9,26 +8,24 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.Objects; +import java.util.LinkedList; +import java.util.Optional; import java.util.stream.Stream; -class UserDefinedConstructorInstantiator extends AbstractObjectInstantiator { +public class UserDefinedConstructorInstantiator extends ObjectInstantiatorAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(BestConstructorInstantiator.class); + private final ConstructorParameters constructorParameters; - UserDefinedConstructorInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + public UserDefinedConstructorInstantiator(final Class clazz, final ConstructorParameters constructorParameters) { + super(clazz); + this.constructorParameters = constructorParameters; } @Override public Object instantiate() { - return constructorParameters.get(clazz) - .stream() - .map(this::createObjectUsingConstructorParameters) - .filter(Objects::nonNull) - .findAny() - .orElseThrow(this::createObjectInstantiationException); + return createObjectUsingConstructorParameters(constructorParameters) + .orElseThrow(this::createObjectInstantiationException); } @Override @@ -36,20 +33,7 @@ public boolean canInstantiate() { return userDefinedConstructorParameters() && !qualifiesForProxy(clazz); } - private boolean userDefinedConstructorParameters() { - return constructorParameters.containsKey(clazz); - } - - private boolean qualifiesForProxy(final Class clazz) { - return clazz.isInterface() || clazz.isAnnotation() || Modifier.isAbstract(clazz.getModifiers()); - } - - private ObjectInstantiationException createObjectInstantiationException() { - return new ObjectInstantiationException(clazz, - "Could not instantiate object by any user defined constructor types and parameters."); - } - - private Object createObjectUsingConstructorParameters(final ConstructorParameters constructorParameters) { + private Optional createObjectUsingConstructorParameters(final ConstructorParameters constructorParameters) { try { Class[] constructorParametersTypes = constructorParameters.getParametersTypes(); Object[] arguments = constructorParameters.getParameters(); @@ -63,17 +47,33 @@ private Object createObjectUsingConstructorParameters(final ConstructorParameter final Constructor constructor = clazz.getDeclaredConstructor(constructorParametersTypes); constructor.setAccessible(true); - return constructor.newInstance(arguments); + return Optional.of(constructor.newInstance(arguments)); } catch (final NoSuchMethodException | InstantiationException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { LOGGER.debug("Exception:", e); - return null; + return Optional.empty(); } } + private boolean userDefinedConstructorParameters() { + return constructorParameters != null; + } + + private boolean qualifiesForProxy(final Class clazz) { + return clazz.isInterface() || clazz.isAnnotation() || Modifier.isAbstract(clazz.getModifiers()); + } + + private ObjectInstantiationException createObjectInstantiationException() { + return new ObjectInstantiationException(clazz, + "Could not instantiate object by any user defined constructor types and parameters."); + } + private Object instantiateEnclosingClass() { final Class enclosingClass = clazz.getEnclosingClass(); - return Instantiable.forClass(enclosingClass, constructorParameters) + // TODO create GH issue and explain why creating enclosing class may fail: + // it will fail if one of enclosing class constructor parameter requires user defined instantiator + // currently there is no workaround for this issue + return Instantiable.forClass(enclosingClass, new LinkedList<>()) .instantiate(); } @@ -93,4 +93,11 @@ private boolean isInnerClass() { return clazz.getEnclosingClass() != null && !Modifier.isStatic(clazz.getModifiers()); } + @Override + public String toString() { + return "UserDefinedConstructorInstantiator{" + + "constructorParameters=" + constructorParameters + + ", clazz=" + clazz + + '}'; + } } diff --git a/src/main/java/pl/pojo/tester/internal/tester/AbstractTester.java b/src/main/java/pl/pojo/tester/internal/tester/AbstractTester.java index 53d2ca94..8461132a 100644 --- a/src/main/java/pl/pojo/tester/internal/tester/AbstractTester.java +++ b/src/main/java/pl/pojo/tester/internal/tester/AbstractTester.java @@ -1,20 +1,19 @@ package pl.pojo.tester.internal.tester; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import pl.pojo.tester.api.ClassAndFieldPredicatePair; -import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.api.FieldPredicate; import pl.pojo.tester.internal.assertion.TestAssertions; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import pl.pojo.tester.internal.field.DefaultFieldValueChanger; +import pl.pojo.tester.internal.instantiator.AbstractObjectInstantiator; import pl.pojo.tester.internal.instantiator.ObjectGenerator; import pl.pojo.tester.internal.utils.Permutator; import pl.pojo.tester.internal.utils.ThoroughFieldPermutator; import java.util.Arrays; +import java.util.LinkedList; import java.util.List; import java.util.function.Predicate; @@ -23,7 +22,7 @@ public abstract class AbstractTester { final TestAssertions testAssertions = new TestAssertions(); ObjectGenerator objectGenerator; - private MultiValuedMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); + private List instantiators = new LinkedList<>(); private AbstractFieldValueChanger fieldValuesChanger = DefaultFieldValueChanger.INSTANCE; private Permutator permutator = new ThoroughFieldPermutator(); @@ -32,7 +31,7 @@ public AbstractTester() { } public AbstractTester(final AbstractFieldValueChanger abstractFieldValueChanger) { - objectGenerator = new ObjectGenerator(abstractFieldValueChanger, constructorParameters, permutator); + objectGenerator = new ObjectGenerator(abstractFieldValueChanger, instantiators, permutator); } public void test(final Class clazz) { @@ -46,7 +45,8 @@ public void test(final Class clazz, final Predicate fieldPredicate) { test(classAndFieldPredicatePair); } - public abstract void test(final ClassAndFieldPredicatePair baseClassAndFieldPredicatePair, final ClassAndFieldPredicatePair... classAndFieldPredicatePairs); + public abstract void test(final ClassAndFieldPredicatePair baseClassAndFieldPredicatePair, + final ClassAndFieldPredicatePair... classAndFieldPredicatePairs); public void testAll(final Class... classes) { final ClassAndFieldPredicatePair[] classesAndFieldPredicatesPairs = Arrays.stream(classes) @@ -64,12 +64,12 @@ public void testAll(final ClassAndFieldPredicatePair... classesAndFieldPredicate public void setFieldValuesChanger(final AbstractFieldValueChanger fieldValuesChanger) { this.fieldValuesChanger = fieldValuesChanger; - objectGenerator = new ObjectGenerator(fieldValuesChanger, constructorParameters, permutator); + objectGenerator = new ObjectGenerator(fieldValuesChanger, instantiators, permutator); } - public void setUserDefinedConstructors(final MultiValuedMap, ConstructorParameters> constructorParameters) { - this.constructorParameters = constructorParameters; - objectGenerator = new ObjectGenerator(fieldValuesChanger, constructorParameters, permutator); + public void setUserDefinedInstantiators(final List instantiators) { + this.instantiators = instantiators; + objectGenerator = new ObjectGenerator(fieldValuesChanger, instantiators, permutator); } @Override @@ -86,7 +86,7 @@ public boolean equals(final Object otherObject) { return new EqualsBuilder().append(objectGenerator, that.objectGenerator) .append(testAssertions, that.testAssertions) - .append(constructorParameters, that.constructorParameters) + .append(instantiators, that.instantiators) .append(fieldValuesChanger, that.fieldValuesChanger) .isEquals(); } @@ -95,15 +95,11 @@ public boolean equals(final Object otherObject) { public int hashCode() { return new HashCodeBuilder().append(objectGenerator) .append(testAssertions) - .append(constructorParameters) + .append(instantiators) .append(fieldValuesChanger) .toHashCode(); } - protected MultiValuedMap, ConstructorParameters> getConstructorParameters() { - return constructorParameters; - } - @Override public String toString() { return this.getClass() diff --git a/src/main/java/pl/pojo/tester/internal/tester/ConstructorTester.java b/src/main/java/pl/pojo/tester/internal/tester/ConstructorTester.java index fcca0726..a4977dc7 100644 --- a/src/main/java/pl/pojo/tester/internal/tester/ConstructorTester.java +++ b/src/main/java/pl/pojo/tester/internal/tester/ConstructorTester.java @@ -4,15 +4,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.pojo.tester.api.ClassAndFieldPredicatePair; -import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.Collection; import java.util.List; -import java.util.function.Predicate; import java.util.stream.Collectors; public class ConstructorTester extends AbstractTester { @@ -28,11 +25,12 @@ public ConstructorTester(final AbstractFieldValueChanger abstractFieldValueChang } @Override - public void test(final ClassAndFieldPredicatePair baseClassAndFieldPredicatePair, final ClassAndFieldPredicatePair... classAndFieldPredicatePairs) { + public void test(final ClassAndFieldPredicatePair baseClassAndFieldPredicatePair, + final ClassAndFieldPredicatePair... classAndFieldPredicatePairs) { final Class testedClass = baseClassAndFieldPredicatePair.getClazz(); if (isAbstract(testedClass)) { LOGGER.info("Tried to test constructor in abstract ({}) class, annotation or interface. " - + "Skipping due to nature of constructors in those classes", testedClass); + + "Skipping due to nature of constructors in those classes", testedClass); return; } final List> declaredConstructors = getNotSyntheticConstructorFromClass(testedClass); @@ -51,40 +49,12 @@ private boolean isNotSynthetic(final Constructor constructor) { } private void tryInstantiate(final Constructor constructor) { - final Object[] parameters; - final Predicate matchingConstructorParameterTypes = ctr -> ctr.matches(constructor.getParameterTypes()); - - if (constructorParametersAreProvided(constructor)) { - final Collection constructorParameters = getConstructorParameters(constructor); - parameters = constructorParameters.stream() - .filter(matchingConstructorParameterTypes) - .map(ConstructorParameters::getParameters) - .findFirst() - .orElseGet(() -> logAndTryToCreateOwnParameters(constructor)); - } else { - parameters = createConstructorParameters(constructor); - } + final Object[] parameters = createConstructorParameters(constructor); testAssertions.assertThatConstructor(constructor) .willInstantiateClassUsing(parameters); } - private Object[] logAndTryToCreateOwnParameters(final Constructor constructor) { - LOGGER.warn("Class '{}' could not be created by constructor '{}' and any user defined parameters.", - constructor.getDeclaringClass(), - constructor); - return createConstructorParameters(constructor); - } - - private Collection getConstructorParameters(final Constructor constructor) { - return getConstructorParameters().get(constructor.getDeclaringClass()); - } - - private boolean constructorParametersAreProvided(final Constructor constructor) { - final Class declaringClass = constructor.getDeclaringClass(); - return getConstructorParameters().containsKey(declaringClass); - } - private Object[] createConstructorParameters(final Constructor constructor) { return Arrays.stream(constructor.getParameterTypes()) .map(objectGenerator::createNewInstance) diff --git a/src/test/java/helpers/MultiValuedMapMatcher.java b/src/test/java/helpers/MultiValuedMapMatcher.java deleted file mode 100644 index 652b666b..00000000 --- a/src/test/java/helpers/MultiValuedMapMatcher.java +++ /dev/null @@ -1,35 +0,0 @@ -package helpers; - -import org.apache.commons.collections4.MultiValuedMap; -import org.mockito.ArgumentMatcher; -import pl.pojo.tester.api.ConstructorParameters; - -import java.util.Arrays; - -public class MultiValuedMapMatcher implements ArgumentMatcher, ConstructorParameters>> { - - private final Class expectedClass; - private final ConstructorParameters expectedArguments; - - public MultiValuedMapMatcher(final Class expectedClass, final ConstructorParameters expectedArguments) { - this.expectedClass = expectedClass; - this.expectedArguments = expectedArguments; - } - - - @Override - public boolean matches(final MultiValuedMap, ConstructorParameters> argument) { - if (!argument.containsKey(expectedClass)) { - return false; - } - return argument.get(expectedClass) - .stream() - .map(actualArgument -> Arrays.equals(actualArgument.getParameters(), - expectedArguments.getParameters()) - && - Arrays.equals(actualArgument.getParametersTypes(), - expectedArguments.getParametersTypes())) - .findAny() - .isPresent(); - } -} diff --git a/src/test/java/pl/pojo/tester/api/assertion/AbstractAssertionTest.java b/src/test/java/pl/pojo/tester/api/assertion/AbstractAssertionTest.java index 61b9a553..4e39dae6 100644 --- a/src/test/java/pl/pojo/tester/api/assertion/AbstractAssertionTest.java +++ b/src/test/java/pl/pojo/tester/api/assertion/AbstractAssertionTest.java @@ -1,7 +1,6 @@ package pl.pojo.tester.api.assertion; import classesForTest.fields.TestEnum1; -import helpers.MultiValuedMapMatcher; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -10,16 +9,22 @@ import pl.pojo.tester.internal.assertion.AbstractAssertionError; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import pl.pojo.tester.internal.field.DefaultFieldValueChanger; -import pl.pojo.tester.internal.utils.SublistFieldPermutator; +import pl.pojo.tester.internal.instantiator.UserDefinedConstructorInstantiator; import pl.pojo.tester.internal.tester.EqualsTester; import pl.pojo.tester.internal.tester.HashCodeTester; import pl.pojo.tester.internal.utils.CollectionUtils; +import pl.pojo.tester.internal.utils.SublistFieldPermutator; import java.util.Random; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.powermock.reflect.Whitebox.getInternalState; import static org.powermock.reflect.Whitebox.setInternalState; @@ -149,24 +154,25 @@ void Should_Set_Field_Value_Changer_To_Testers() { } @Test - void Should_Set_User_Defined_Class_And_Constructor_Parameters_To_Tester() { + void Should_Set_Instantiators_To_Tester() { // given final AbstractAssertion abstractAssertion = new AbstractAssertionImplementation(); final EqualsTester equalsTester = mock(EqualsTester.class); setInternalState(abstractAssertion, "testers", CollectionUtils.asSet(equalsTester)); final Class expectedClass = String.class; - final Object[] expectedArguments = {'c', 'h', 'a', 'r'}; - final Class[] expectedTypes = {char.class, char.class, char.class, char.class}; - final ConstructorParameters expectedConstructorParameters = new ConstructorParameters(expectedArguments, - expectedTypes); - abstractAssertion.create(expectedClass, expectedConstructorParameters); + final Object[] expectedArguments = { 'c', 'h', 'a', 'r' }; + final Class[] expectedTypes = { char.class, char.class, char.class, char.class }; + final ConstructorParameters constructorParameters = new ConstructorParameters(expectedArguments, + expectedTypes); + final UserDefinedConstructorInstantiator instantiator = new UserDefinedConstructorInstantiator(expectedClass, + constructorParameters); + abstractAssertion.create(expectedClass, instantiator::instantiate); // when abstractAssertion.areWellImplemented(); // then - verify(equalsTester, times(1)).setUserDefinedConstructors(argThat(new MultiValuedMapMatcher(expectedClass, - expectedConstructorParameters))); + verify(equalsTester, times(1)).setUserDefinedInstantiators(any()); } @Test @@ -176,8 +182,8 @@ void Should_Call_Next_Create_Method() { final EqualsTester equalsTester = mock(EqualsTester.class); setInternalState(abstractAssertion, "testers", CollectionUtils.asSet(equalsTester)); final Class expectedClass = String.class; - final Object[] expectedArguments = {'c', 'h', 'a', 'r'}; - final Class[] expectedTypes = {char.class, char.class, char.class, char.class}; + final Object[] expectedArguments = { 'c', 'h', 'a', 'r' }; + final Class[] expectedTypes = { char.class, char.class, char.class, char.class }; final ConstructorParameters expectedConstructorParameters = new ConstructorParameters(expectedArguments, expectedTypes); abstractAssertion.create(expectedClass, expectedArguments, expectedTypes); @@ -189,26 +195,27 @@ void Should_Call_Next_Create_Method() { verify(abstractAssertion).create(eq(expectedClass), eq(expectedConstructorParameters)); } - @Test - void Should_Set_User_Defined_Class_And_Constructor_Parameters_To_Tester_Using_Class_Name() { - // given - final AbstractAssertion abstractAssertion = new AbstractAssertionImplementation(); - final EqualsTester equalsTester = mock(EqualsTester.class); - setInternalState(abstractAssertion, "testers", CollectionUtils.asSet(equalsTester)); - final Class expectedClass = String.class; - final Object[] expectedArguments = {'c', 'h', 'a', 'r'}; - final Class[] expectedTypes = {char.class, char.class, char.class, char.class}; - final ConstructorParameters expectedConstructorParameters = new ConstructorParameters(expectedArguments, - expectedTypes); - abstractAssertion.create("java.lang.String", expectedConstructorParameters); - - // when - abstractAssertion.areWellImplemented(); - - // then - verify(equalsTester, times(1)).setUserDefinedConstructors(argThat(new MultiValuedMapMatcher(expectedClass, - expectedConstructorParameters))); - } + // TODO verify this +// @Test +// void Should_Set_Instantiators_To_Tester_Using_Class_Name() { +// // given +// final AbstractAssertion abstractAssertion = new AbstractAssertionImplementation(); +// final EqualsTester equalsTester = mock(EqualsTester.class); +// setInternalState(abstractAssertion, "testers", CollectionUtils.asSet(equalsTester)); +// final Class expectedClass = String.class; +// final Object[] expectedArguments = { 'c', 'h', 'a', 'r' }; +// final Class[] expectedTypes = { char.class, char.class, char.class, char.class }; +// final ConstructorParameters expectedConstructorParameters = new ConstructorParameters(expectedArguments, +// expectedTypes); +// abstractAssertion.create("java.lang.String", expectedConstructorParameters); +// +// // when +// abstractAssertion.areWellImplemented(); +// +// // then +// verify(equalsTester, times(1)).setUserDefinedInstantiators(argThat(new MultiValuedMapMatcher(expectedClass, +// expectedConstructorParameters))); +// } @Test void Should_Call_Next_Create_Method_Using_Class_Name() { @@ -216,8 +223,8 @@ void Should_Call_Next_Create_Method_Using_Class_Name() { final AbstractAssertion abstractAssertion = spy(new AbstractAssertionImplementation()); final EqualsTester equalsTester = mock(EqualsTester.class); setInternalState(abstractAssertion, "testers", CollectionUtils.asSet(equalsTester)); - final Object[] expectedArguments = {'c', 'h', 'a', 'r'}; - final Class[] expectedTypes = {char.class, char.class, char.class, char.class}; + final Object[] expectedArguments = { 'c', 'h', 'a', 'r' }; + final Class[] expectedTypes = { char.class, char.class, char.class, char.class }; final ConstructorParameters expectedConstructorParameters = new ConstructorParameters(expectedArguments, expectedTypes); final String expectedClassName = "java.lang.String"; diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiatorTest.java index f2f8c83b..4c743783 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/AbstractMultiConstructorInstantiatorTest.java @@ -1,12 +1,10 @@ package pl.pojo.tester.internal.instantiator; import lombok.Data; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.Test; -import pl.pojo.tester.api.ConstructorParameters; import java.lang.reflect.Constructor; +import java.util.LinkedList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -14,45 +12,11 @@ class AbstractMultiConstructorInstantiatorTest { - @Test - void Should_Create_Object_Using_User_Parameters() { - // given - final ArrayListValuedHashMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); - final Class clazz = A.class; - constructorParameters.put(clazz, new ConstructorParameters(new Object[]{ 12345 }, new Class[]{ int.class })); - final AbstractMultiConstructorInstantiator instantiator = new MockMultiConstructorInstantiator(clazz, - constructorParameters); - final A expectedResult = new A(12345); - - // when - final Object result = instantiator.instantiateUsingUserParameters(); - - // then - assertThat(result).isEqualTo(expectedResult); - } - - @Test - void Should_Return_Null_If_Parameters_For_This_Class_Are_Empty() { - // given - final ArrayListValuedHashMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); - final Class clazz = A.class; - final AbstractMultiConstructorInstantiator instantiator = new MockMultiConstructorInstantiator(clazz, - constructorParameters); - - // when - final Object result = instantiator.instantiateUsingUserParameters(); - - // then - assertThat(result).isNull(); - } - @Test void Should_Throw_Exception_If_Constructor_Throws_Exception() { // given - final ArrayListValuedHashMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); final Class clazz = B.class; - final AbstractMultiConstructorInstantiator instantiator = new MockMultiConstructorInstantiator(clazz, - constructorParameters); + final AbstractMultiConstructorInstantiator instantiator = new MockMultiConstructorInstantiator(clazz); final Throwable expectedResult = new ObjectInstantiationException(B.class, "msg", null); // when @@ -63,9 +27,8 @@ void Should_Throw_Exception_If_Constructor_Throws_Exception() { } static class MockMultiConstructorInstantiator extends AbstractMultiConstructorInstantiator { - MockMultiConstructorInstantiator(final Class clazz, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - super(clazz, constructorParameters); + MockMultiConstructorInstantiator(final Class clazz) { + super(clazz, new LinkedList<>()); } @Override diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/ArrayInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/ArrayInstantiatorTest.java index 8eb7a755..c8d0db7f 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/ArrayInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/ArrayInstantiatorTest.java @@ -1,7 +1,6 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; @@ -39,8 +38,7 @@ Stream Should_Create_Array_By_Class() { private Executable Should_Create_Array(final Class classToInstantiate) { return () -> { // given - final ArrayInstantiator instantiator = new ArrayInstantiator(classToInstantiate, - new ArrayListValuedHashMap<>()); + final ArrayInstantiator instantiator = new ArrayInstantiator(classToInstantiate); // when final Object result = instantiator.instantiate(); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiatorTest.java index 04065a18..653ff0fb 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/BestConstructorInstantiatorTest.java @@ -1,10 +1,15 @@ package pl.pojo.tester.internal.instantiator; -import classesForTest.*; +import classesForTest.ClassContainingStaticClasses; +import classesForTest.Constructor_Stream; +import classesForTest.Constructor_Thread; +import classesForTest.Constructors_First_Throws_Exception; +import classesForTest.PackageConstructor; +import classesForTest.Person; +import classesForTest.PrivateConstructor; +import classesForTest.ProtectedConstructor; import lombok.EqualsAndHashCode; import lombok.ToString; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; @@ -14,6 +19,8 @@ import pl.pojo.tester.internal.utils.FieldUtils; import pl.pojo.tester.internal.utils.MethodUtils; +import java.util.ArrayList; +import java.util.List; import java.util.stream.Stream; import static helpers.TestHelper.getDefaultDisplayName; @@ -24,8 +31,6 @@ class BestConstructorInstantiatorTest { - private final MultiValuedMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); - @TestFactory Stream Should_Instantiate_Non_Public_Classes() { return Stream.of("classesForTest.UnpublicClass", @@ -62,7 +67,7 @@ private Executable Should_Instantiate_Non_Public_Classes(final String className) // given final Class classUnderTest = Class.forName(className); final BestConstructorInstantiator instantiator = new BestConstructorInstantiator(classUnderTest, - constructorParameters); + new ArrayList<>()); // when final Object result = instantiator.instantiate(); @@ -113,7 +118,7 @@ private Executable Should_Create_Object_Using_Best_Constructor(final Class cl return () -> { // given final BestConstructorInstantiator instantiator = new BestConstructorInstantiator(classToInstantiate, - constructorParameters); + new ArrayList<>()); // when final Object result = instantiator.instantiate(); @@ -135,7 +140,7 @@ private Executable Should_Throw_Exception_When_Cannot_Instantiate_Class(final Cl return () -> { // given final BestConstructorInstantiator instantiator = new BestConstructorInstantiator(classToInstantiate, - constructorParameters); + new ArrayList<>()); // when final Throwable result = catchThrowable(instantiator::instantiate); @@ -150,7 +155,7 @@ void Should_Create_Object_Using_Private_Constructor() { // given final Class classToInstantiate = PrivateConstructor.class; final BestConstructorInstantiator instantiator = new BestConstructorInstantiator(classToInstantiate, - constructorParameters); + new ArrayList<>()); // when final Object result = instantiator.instantiate(); @@ -164,7 +169,7 @@ void Should_Create_Object_With_Second_Constructor_If_First_Threw_exception() { // given final Class classToInstantiate = Constructors_First_Throws_Exception.class; final BestConstructorInstantiator instantiator = new BestConstructorInstantiator(classToInstantiate, - constructorParameters); + new ArrayList<>()); // when final Object result = instantiator.instantiate(); @@ -176,12 +181,12 @@ void Should_Create_Object_With_Second_Constructor_If_First_Threw_exception() { @Test void Should_Create_Object_With_User_Defined_Constructor_Parameters() { // given - final ArrayListValuedHashMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); - final ConstructorParameters parameters = new ConstructorParameters(new Object[]{"expectedString"}, - new Class[]{Object.class}); - constructorParameters.put(NoDefaultConstructor.class, parameters); + final List instantiators = new ArrayList<>(); + final ConstructorParameters parameters = new ConstructorParameters(new Object[]{ "expectedString" }, + new Class[]{ Object.class }); + instantiators.add(new UserDefinedConstructorInstantiator(NoDefaultConstructor.class, parameters)); final BestConstructorInstantiator instantiator = new BestConstructorInstantiator(NoDefaultConstructor.class, - constructorParameters); + instantiators); final NoDefaultConstructor expectedResult = new NoDefaultConstructor("expectedString"); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/CollectionInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/CollectionInstantiatorTest.java index 65af4e20..ddc91515 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/CollectionInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/CollectionInstantiatorTest.java @@ -1,6 +1,5 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; @@ -71,8 +70,7 @@ Stream Should_Return_Expected_Collection_Object() { private Executable Should_Return_Expected_Collection_Object(final Class classToInstantiate) { return () -> { // given - final CollectionInstantiator instantiator = new CollectionInstantiator(classToInstantiate, - new ArrayListValuedHashMap<>()); + final CollectionInstantiator instantiator = new CollectionInstantiator(classToInstantiate); // when final Object result = instantiator.instantiate(); @@ -85,8 +83,7 @@ private Executable Should_Return_Expected_Collection_Object(final Class class @Test void Should_Throws_Exception_When_Prepared_Objects_Do_Not_Contain_Expected_Class() { // given - final CollectionInstantiator instantiator = new CollectionInstantiator(String.class, - new ArrayListValuedHashMap<>()); + final CollectionInstantiator instantiator = new CollectionInstantiator(String.class); // when final Throwable result = catchThrowable(instantiator::instantiate); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiatorTest.java index a2833fdd..b9366fb6 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/DefaultConstructorInstantiatorTest.java @@ -1,7 +1,6 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,8 +13,7 @@ class DefaultConstructorInstantiatorTest { void Should_Create_Object_Using_Default_Constructor() { // given final Class classToInstantiate = String.class; - final DefaultConstructorInstantiator instantiator = new DefaultConstructorInstantiator(classToInstantiate, - new ArrayListValuedHashMap<>()); + final DefaultConstructorInstantiator instantiator = new DefaultConstructorInstantiator(classToInstantiate); // when final Object result = instantiator.instantiate(); @@ -28,8 +26,7 @@ void Should_Create_Object_Using_Default_Constructor() { void Should_Throw_Exception_When_Cannot_Instantiate_Object() { // given final Class classToInstantiate = No_Args_Constructor_Throws_IllegalAccessException.class; - final DefaultConstructorInstantiator instantiator = new DefaultConstructorInstantiator(classToInstantiate, - new ArrayListValuedHashMap<>()); + final DefaultConstructorInstantiator instantiator = new DefaultConstructorInstantiator(classToInstantiate); // when final Throwable result = catchThrowable(instantiator::instantiate); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/EnumInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/EnumInstantiatorTest.java index f4f1d243..0d8efa69 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/EnumInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/EnumInstantiatorTest.java @@ -2,7 +2,6 @@ import classesForTest.EmptyEnum; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,7 +12,7 @@ public class EnumInstantiatorTest { @Test void Should_Return_Null_When_Enum_Is_Empty() { // given - final EnumInstantiator instantiator = new EnumInstantiator(EmptyEnum.class, new ArrayListValuedHashMap<>()); + final EnumInstantiator instantiator = new EnumInstantiator(EmptyEnum.class); // when final Object result = instantiator.instantiate(); @@ -26,7 +25,7 @@ void Should_Return_Null_When_Enum_Is_Empty() { void Should_Return_Any_Enum_Value() { // given final Class doubleEnumClass = DoubleEnum.class; - final EnumInstantiator instantiator = new EnumInstantiator(doubleEnumClass, new ArrayListValuedHashMap<>()); + final EnumInstantiator instantiator = new EnumInstantiator(doubleEnumClass); // when final Object result = instantiator.instantiate(); @@ -39,7 +38,7 @@ void Should_Return_Any_Enum_Value() { void Should_Return_One_Enum_Value() { // given final Class oneEnumClass = OneEnum.class; - final EnumInstantiator instantiator = new EnumInstantiator(oneEnumClass, new ArrayListValuedHashMap<>()); + final EnumInstantiator instantiator = new EnumInstantiator(oneEnumClass); // when final Object result = instantiator.instantiate(); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/InstantiableTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/InstantiableTest.java index 9a8e0a71..23e86807 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/InstantiableTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/InstantiableTest.java @@ -7,14 +7,11 @@ import classesForTest.EmptyEnum; import lombok.AllArgsConstructor; import lombok.Data; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; -import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.internal.field.date.DefaultDateAndTimeFieldValueChanger; import java.io.Serializable; @@ -49,11 +46,11 @@ class InstantiableTest { - private static final MultiValuedMap, ConstructorParameters> CLASS_AND_CONSTRUCTOR_PARAMETERS = new ArrayListValuedHashMap<>(); + private static final List INSTANTIATORS = new LinkedList<>(); @BeforeAll static void beforeAll() { - CLASS_AND_CONSTRUCTOR_PARAMETERS.put(UserDefinedClass.class, null); + INSTANTIATORS.add(new SupplierInstantiator(UserDefinedClass.class, () -> null)); } @TestFactory @@ -69,7 +66,7 @@ Stream Should_Return_Expected_Instantiator_For_Class() { new ClassInstantiator(Constructor_Stream.class, BestConstructorInstantiator.class), new ClassInstantiator(Constructor_Thread.class, BestConstructorInstantiator.class), new ClassInstantiator(String.class, JavaTypeInstantiator.class), - new ClassInstantiator(UserDefinedClass.class, UserDefinedConstructorInstantiator.class), + new ClassInstantiator(UserDefinedClass.class, SupplierInstantiator.class), new ClassInstantiator(Boolean[].class, ArrayInstantiator.class), new ClassInstantiator(Byte[].class, ArrayInstantiator.class), new ClassInstantiator(Character[].class, ArrayInstantiator.class), @@ -146,7 +143,7 @@ Stream Should_Return_Expected_Instantiator_For_Class() { private Executable Should_Return_Expected_Instantiator_For_Class(final ClassInstantiator testCase) { return () -> { // when - final Object result = Instantiable.forClass(testCase.clazz, CLASS_AND_CONSTRUCTOR_PARAMETERS); + final Object result = Instantiable.forClass(testCase.clazz, INSTANTIATORS); // then assertThat(result).isInstanceOf(testCase.instantiator); @@ -159,7 +156,7 @@ void Should_Instantiate_Two_Classes() { final Class[] classesToInstantiate = { A.class, B.class }; // when - final Object[] result = Instantiable.instantiateClasses(classesToInstantiate, new ArrayListValuedHashMap<>()); + final Object[] result = Instantiable.instantiateClasses(classesToInstantiate, new ArrayList<>()); // then assertThat(result).extracting(Object::getClass) @@ -167,28 +164,27 @@ void Should_Instantiate_Two_Classes() { } @Test - void Should_Return_User_Defined_Constructor_Instantiator_If_Class_Does_Not_Qualifies_For_Proxy_And() { + void Should_Return_Instantiator_Defined_By_User() { // given - final ArrayListValuedHashMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); + final List instantiators = new ArrayList<>(); final Class clazz = A.class; - constructorParameters.put(clazz, new ConstructorParameters(new Object[0], new Class[0])); + final SupplierInstantiator expectedInstantiator = new SupplierInstantiator(clazz, () -> new Object[0]); + instantiators.add(expectedInstantiator); // when - final AbstractObjectInstantiator result = Instantiable.forClass(clazz, constructorParameters); + final AbstractObjectInstantiator result = Instantiable.forClass(clazz, instantiators); // then - assertThat(result).isInstanceOf(UserDefinedConstructorInstantiator.class); + assertThat(result).isEqualTo(expectedInstantiator); } @Test - void Should_Return_Proxy_Instantiator_If_Class_Qualifies_For_Proxy_And_User_Defined_Constructor_Parameters() { + void Should_Return_Proxy_Instantiator_If_Class_Qualifies_For_Proxy() { // given - final ArrayListValuedHashMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); final Class clazz = Abstract.class; - constructorParameters.put(clazz, new ConstructorParameters(new Object[0], new Class[0])); // when - final AbstractObjectInstantiator result = Instantiable.forClass(clazz, constructorParameters); + final AbstractObjectInstantiator result = Instantiable.forClass(clazz, new ArrayList<>()); // then assertThat(result).isInstanceOf(ProxyInstantiator.class); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiatorTest.java index e4e00488..a9efea71 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/JavaTypeInstantiatorTest.java @@ -1,6 +1,5 @@ package pl.pojo.tester.internal.instantiator; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; @@ -57,8 +56,7 @@ Stream Should_Instantiate_Primitive() { private Executable Should_Instantiate_Primitive(final Class classToInstantiate) { return () -> { // given - final JavaTypeInstantiator instantiator = new JavaTypeInstantiator(classToInstantiate, - new ArrayListValuedHashMap<>()); + final JavaTypeInstantiator instantiator = new JavaTypeInstantiator(classToInstantiate); // when final Object result = instantiator.instantiate(); @@ -107,8 +105,7 @@ Stream Should_Instantiate_Java_Type_Classes() { private Executable Should_Instantiate_Java_Type_Classes(final Class classToInstantiate) { return () -> { // given - final JavaTypeInstantiator instantiator = new JavaTypeInstantiator(classToInstantiate, - new ArrayListValuedHashMap<>()); + final JavaTypeInstantiator instantiator = new JavaTypeInstantiator(classToInstantiate); // when final Object result = instantiator.instantiate(); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorFastTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorFastTest.java index c57a7de0..26fca4e4 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorFastTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorFastTest.java @@ -14,8 +14,6 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -24,11 +22,11 @@ import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; import pl.pojo.tester.api.ClassAndFieldPredicatePair; -import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import pl.pojo.tester.internal.field.DefaultFieldValueChanger; import pl.pojo.tester.internal.utils.SublistFieldPermutator; +import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.UUID; @@ -42,18 +40,15 @@ class ObjectGeneratorFastTest { private final AbstractFieldValueChanger abstractFieldValueChanger = DefaultFieldValueChanger.INSTANCE; - private final MultiValuedMap, ConstructorParameters> constructorParameters = new - ArrayListValuedHashMap<>(); - private ObjectGenerator makeObjectGenerator(final AbstractFieldValueChanger abstractFieldValueChanger, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - return new ObjectGenerator(abstractFieldValueChanger, constructorParameters, new SublistFieldPermutator()); + private ObjectGenerator makeObjectGenerator(final AbstractFieldValueChanger abstractFieldValueChanger) { + return new ObjectGenerator(abstractFieldValueChanger, new LinkedList<>(), new SublistFieldPermutator()); } @Test void Should_Generate_Different_Objects_For_Class_Containing_Boolean_Type() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair classAndFieldPredicatePair = new ClassAndFieldPredicatePair( ClassWithBooleanField.class); @@ -68,7 +63,7 @@ void Should_Generate_Different_Objects_For_Class_Containing_Boolean_Type() { @Test void Should_Generate_Different_Objects_For_Class_With_Private_Enum() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair classAndFieldPredicatePair = new ClassAndFieldPredicatePair( ClassContainingPrivateEnum.class); @@ -83,7 +78,7 @@ void Should_Generate_Different_Objects_For_Class_With_Private_Enum() { @Test void Should_Create_Any_Instance() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final Class expectedClass = GoodPojo_Equals_HashCode_ToString.class; // when @@ -105,8 +100,7 @@ Stream Should_Create_Same_Instance() { private Executable Should_Create_Same_Instance(final Object objectToCreateSameInstance) { return () -> { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, - constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); // when final Object result = objectGenerator.generateSameInstance(objectToCreateSameInstance); @@ -150,8 +144,7 @@ Stream Should_Generate_Different_Objects() { private Executable Should_Generate_Different_Objects(final DifferentObjectTestCase testCase) { return () -> { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, - constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair classAndFieldPredicatePair = new ClassAndFieldPredicatePair(testCase.clazz); // when @@ -189,8 +182,7 @@ Stream Should_Generate_Different_Objects_Recursively() { public Executable Should_Generate_Different_Objects_Recursively(final RecursivelyDifferentObjectTestCase testCase) { return () -> { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, - constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); // when final List result = objectGenerator.generateDifferentObjects(testCase.baseClass, @@ -205,7 +197,7 @@ public Executable Should_Generate_Different_Objects_Recursively(final Recursivel @Test void Should_Not_Fall_In_Endless_Loop() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair iClass = new ClassAndFieldPredicatePair(R.class); final int expectedSize = 2; diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorTest.java index a0e5426d..ad30c411 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/ObjectGeneratorTest.java @@ -14,8 +14,6 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -24,11 +22,11 @@ import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; import pl.pojo.tester.api.ClassAndFieldPredicatePair; -import pl.pojo.tester.api.ConstructorParameters; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import pl.pojo.tester.internal.field.DefaultFieldValueChanger; import pl.pojo.tester.internal.utils.ThoroughFieldPermutator; +import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.UUID; @@ -42,18 +40,15 @@ class ObjectGeneratorTest { private final AbstractFieldValueChanger abstractFieldValueChanger = DefaultFieldValueChanger.INSTANCE; - private final MultiValuedMap, ConstructorParameters> constructorParameters = new - ArrayListValuedHashMap<>(); - private ObjectGenerator makeObjectGenerator(final AbstractFieldValueChanger abstractFieldValueChanger, - final MultiValuedMap, ConstructorParameters> constructorParameters) { - return new ObjectGenerator(abstractFieldValueChanger, constructorParameters, new ThoroughFieldPermutator()); + private ObjectGenerator makeObjectGenerator(final AbstractFieldValueChanger abstractFieldValueChanger) { + return new ObjectGenerator(abstractFieldValueChanger, new LinkedList<>(), new ThoroughFieldPermutator()); } @Test void Should_Generate_Different_Objects_For_Class_Containing_Boolean_Type() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair classAndFieldPredicatePair = new ClassAndFieldPredicatePair( ClassWithBooleanField.class); @@ -68,7 +63,7 @@ void Should_Generate_Different_Objects_For_Class_Containing_Boolean_Type() { @Test void Should_Generate_Different_Objects_For_Class_With_Private_Enum() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair classAndFieldPredicatePair = new ClassAndFieldPredicatePair( ClassContainingPrivateEnum.class); @@ -83,7 +78,7 @@ void Should_Generate_Different_Objects_For_Class_With_Private_Enum() { @Test void Should_Create_Any_Instance() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final Class expectedClass = GoodPojo_Equals_HashCode_ToString.class; // when @@ -105,8 +100,7 @@ Stream Should_Create_Same_Instance() { private Executable Should_Create_Same_Instance(final Object objectToCreateSameInstance) { return () -> { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, - constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); // when final Object result = objectGenerator.generateSameInstance(objectToCreateSameInstance); @@ -150,8 +144,7 @@ Stream Should_Generate_Different_Objects() { private Executable Should_Generate_Different_Objects(final DifferentObjectTestCase testCase) { return () -> { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, - constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair classAndFieldPredicatePair = new ClassAndFieldPredicatePair(testCase.clazz); // when @@ -189,8 +182,7 @@ Stream Should_Generate_Different_Objects_Recursively() { private Executable Should_Generate_Different_Objects_Recursively(final RecursivelyDifferentObjectTestCase testCase) { return () -> { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, - constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); // when final List result = objectGenerator.generateDifferentObjects(testCase.baseClass, @@ -205,7 +197,7 @@ private Executable Should_Generate_Different_Objects_Recursively(final Recursive @Test void Should_Not_Fall_In_Endless_Loop() { // given - final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger, constructorParameters); + final ObjectGenerator objectGenerator = makeObjectGenerator(abstractFieldValueChanger); final ClassAndFieldPredicatePair iClass = new ClassAndFieldPredicatePair(R.class); final int expectedSize = 2; diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/ProxyInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/ProxyInstantiatorTest.java index 8bac12ff..98ae1518 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/ProxyInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/ProxyInstantiatorTest.java @@ -6,14 +6,12 @@ import classesForTest.Annotation; import classesForTest.Interface; import lombok.Data; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; -import pl.pojo.tester.api.ConstructorParameters; +import java.util.LinkedList; import java.util.stream.Stream; import static helpers.TestHelper.getDefaultDisplayName; @@ -23,7 +21,6 @@ class ProxyInstantiatorTest { - private final MultiValuedMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); @TestFactory Stream Should_Instantiate_Abstract_Interface_Or_Annotation_Classes() { @@ -35,7 +32,7 @@ Stream Should_Instantiate_Abstract_Interface_Or_Annotation_Classes( private Executable Should_Instantiate_Abstract_Interface_Or_Annotation_Classes(final Class classToInstantiate) { return () -> { // given - final ProxyInstantiator instantiator = new ProxyInstantiator(classToInstantiate, constructorParameters); + final ProxyInstantiator instantiator = new ProxyInstantiator(classToInstantiate, new LinkedList<>()); // when final Object result = instantiator.instantiate(); @@ -48,7 +45,7 @@ private Executable Should_Instantiate_Abstract_Interface_Or_Annotation_Classes(f @Test void Should_Create_Java_Proxy_Which_Returns_Expected_Values() { // given - final ProxyInstantiator instantiator = new ProxyInstantiator(Interface.class, constructorParameters); + final ProxyInstantiator instantiator = new ProxyInstantiator(Interface.class, new LinkedList<>()); // when final Object result = instantiator.instantiate(); @@ -70,7 +67,7 @@ private Executable Should_Create_Abstract_Class_Without_Default_Constructor(fina return () -> { // given - final ProxyInstantiator instantiator = new ProxyInstantiator(classToInstantiate, constructorParameters); + final ProxyInstantiator instantiator = new ProxyInstantiator(classToInstantiate, new LinkedList<>()); // when final Object result = instantiator.instantiate(); diff --git a/src/test/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiatorTest.java b/src/test/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiatorTest.java index 95dbbfa2..6d8fc830 100644 --- a/src/test/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiatorTest.java +++ b/src/test/java/pl/pojo/tester/internal/instantiator/UserDefinedConstructorInstantiatorTest.java @@ -2,8 +2,6 @@ import lombok.AllArgsConstructor; import lombok.Data; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; @@ -20,30 +18,13 @@ class UserDefinedConstructorInstantiatorTest { - private final MultiValuedMap, ConstructorParameters> constructorParameters = new ArrayListValuedHashMap<>(); - - { - constructorParameters.put(UserDefinedClass.class, - new ConstructorParameters(new Object[]{1, 2}, new Class[]{int.class, int.class})); - constructorParameters.put(ClassWithPrivateConstructor.class, - new ConstructorParameters(new Object[]{1}, new Class[]{int.class})); - constructorParameters.put(One_Arg_Constructor_Throws_NPE.class, - new ConstructorParameters(new Object[]{1}, new Class[]{Object.class})); - constructorParameters.put(No_Args_Constructor_Throws_NPE.class, - new ConstructorParameters(new Object[0], new Class[0])); - constructorParameters.put(InnerClass.class, - new ConstructorParameters(new Object[]{1}, new Class[]{int.class})); - constructorParameters.put(NestedClass.class, - new ConstructorParameters(new Object[]{1}, new Class[]{int.class})); - } - @Test void Should_Create_Object_Using_Private_Constructor() { // given final Class classToInstantiate = ClassWithPrivateConstructor.class; final UserDefinedConstructorInstantiator instantiator = new UserDefinedConstructorInstantiator( classToInstantiate, - constructorParameters); + new ConstructorParameters(new Object[]{ 1 }, new Class[]{ int.class })); // when final Object result = instantiator.instantiate(); @@ -58,7 +39,7 @@ void Should_Create_Object_For_Inner_Class() { final Class classToInstantiate = InnerClass.class; final UserDefinedConstructorInstantiator instantiator = new UserDefinedConstructorInstantiator( classToInstantiate, - constructorParameters); + new ConstructorParameters(new Object[]{ 1 }, new Class[]{ int.class })); // when final Object result = instantiator.instantiate(); @@ -73,7 +54,7 @@ void Should_Create_Object_For_Nested_Class() { final Class classToInstantiate = NestedClass.class; final UserDefinedConstructorInstantiator instantiator = new UserDefinedConstructorInstantiator( classToInstantiate, - constructorParameters); + new ConstructorParameters(new Object[]{ 1 }, new Class[]{ int.class })); // when final Object result = instantiator.instantiate(); @@ -95,7 +76,7 @@ private Executable Should_Throw_Exception_When_Cannot_Instantiate_Class(final Cl // given final UserDefinedConstructorInstantiator instantiator = new UserDefinedConstructorInstantiator( classToInstantiate, - constructorParameters); + new ConstructorParameters(new Object[0], new Class[0])); // when final Throwable result = catchThrowable(instantiator::instantiate); diff --git a/src/test/java/pl/pojo/tester/internal/tester/AbstractTesterTest.java b/src/test/java/pl/pojo/tester/internal/tester/AbstractTesterTest.java index 7a9cbc53..5b144bb3 100644 --- a/src/test/java/pl/pojo/tester/internal/tester/AbstractTesterTest.java +++ b/src/test/java/pl/pojo/tester/internal/tester/AbstractTesterTest.java @@ -4,17 +4,21 @@ import helpers.RecursivelyEqualArgumentMatcher; import helpers.StringPredicateArgumentMatcher; import lombok.Data; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.junit.jupiter.api.Test; import pl.pojo.tester.api.ClassAndFieldPredicatePair; import pl.pojo.tester.internal.field.AbstractFieldValueChanger; import pl.pojo.tester.internal.field.DefaultFieldValueChanger; import pl.pojo.tester.internal.instantiator.ObjectGenerator; +import java.util.LinkedList; import java.util.function.Predicate; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; class AbstractTesterTest { @@ -105,7 +109,7 @@ void Should_Create_New_Object_Generator_When_User_Defined_Class_And_Constructor( final ObjectGenerator beforeChange = abstractTester.objectGenerator; // when - abstractTester.setUserDefinedConstructors(new ArrayListValuedHashMap<>()); + abstractTester.setUserDefinedInstantiators(new LinkedList<>()); final ObjectGenerator afterChange = abstractTester.objectGenerator; diff --git a/src/test/java/pl/pojo/tester/internal/tester/ConstructorTesterTest.java b/src/test/java/pl/pojo/tester/internal/tester/ConstructorTesterTest.java index bc66d9b8..54f12c0b 100644 --- a/src/test/java/pl/pojo/tester/internal/tester/ConstructorTesterTest.java +++ b/src/test/java/pl/pojo/tester/internal/tester/ConstructorTesterTest.java @@ -17,6 +17,8 @@ import pl.pojo.tester.internal.utils.ReflectionUtils; import pl.pojo.tester.internal.utils.Sublists; +import java.util.ArrayList; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; import static org.mockito.Mockito.never; @@ -76,35 +78,14 @@ void Should_Fail_Constructor_Tests() { } @Test - void Should_Use_User_Constructor_Parameters() { - // given - final Class[] classesToTest = { ClassWithSyntheticConstructor.class }; - - final ConstructorParameters parameters = new ConstructorParameters(new Object[]{ "string" }, - new Class[]{ String.class }); - final MultiValuedMap, ConstructorParameters> constructorParameters = spy(new ArrayListValuedHashMap<>()); - constructorParameters.put(ClassWithSyntheticConstructor.class, parameters); - - final ConstructorTester constructorTester = new ConstructorTester(); - constructorTester.setUserDefinedConstructors(constructorParameters); - - // when - final Throwable result = catchThrowable(() -> constructorTester.testAll(classesToTest)); - - // then - assertThat(result).isNull(); - verify(constructorParameters).get(ClassWithSyntheticConstructor.class); - } - - @Test - void Should_Create_Constructor_Parameters_When_Parameters_Are_Not_Provided() { + void Should_Create_Constructor_Parameters() { // given final Class[] classesToTest = { ClassWithSyntheticConstructor.class }; final MultiValuedMap, ConstructorParameters> constructorParameters = spy(new ArrayListValuedHashMap<>()); final ConstructorTester constructorTester = new ConstructorTester(); - constructorTester.setUserDefinedConstructors(constructorParameters); + constructorTester.setUserDefinedInstantiators(new ArrayList<>()); // when final Throwable result = catchThrowable(() -> constructorTester.testAll(classesToTest)); @@ -114,31 +95,6 @@ void Should_Create_Constructor_Parameters_When_Parameters_Are_Not_Provided() { verify(constructorParameters, never()).get(ClassWithSyntheticConstructor.class); } - @Test - void Should_Create_Constructor_Parameters_When_Could_Not_Find_Matching_Constructor_Parameters_Types() { - // given - final Class[] classesToTest = { ClassWithSyntheticConstructor.class }; - - final ConstructorParameters parameters = spy(new ConstructorParameters(new Object[]{ "to", - "many", - "parameters" }, - new Class[]{ String.class, - String.class, - String.class })); - final MultiValuedMap, ConstructorParameters> constructorParameters = spy(new ArrayListValuedHashMap<>()); - constructorParameters.put(ClassWithSyntheticConstructor.class, parameters); - - final ConstructorTester constructorTester = new ConstructorTester(); - constructorTester.setUserDefinedConstructors(constructorParameters); - - // when - final Throwable result = catchThrowable(() -> constructorTester.testAll(classesToTest)); - - // then - assertThat(result).isNull(); - verify(parameters, never()).getParameters(); - } - private static class Pojo { Pojo() { }