From f918b70d5eb75308a14729425beb526a4339c1ba Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 13 Apr 2017 18:59:11 +0200 Subject: [PATCH] generic Pojo (getter+setter) testing --- .../de/hsadmin/bo/customer/MemberShare.java | 7 +- .../de/hsadmin/bo/domain/DomainOption.java | 6 +- .../java/de/hsadmin/bo/pac/PacComponent.java | 2 +- .../customer/CustomerPackageBoPojoTest.java | 23 +++++++ .../hsadmin/bo/customer/MemberShareTest.java | 36 ++++++++++ .../bo/domain/DomainPackageBoTest.java | 18 +++++ .../hsadmin/bo/pac/PacPackageBoPojoTest.java | 25 +++++++ .../hsadmin/dao/customer/CustomerDaoTest.java | 2 +- .../java/de/hsadmin/test/PojoTestUtil.java | 68 +++++++++++++++++++ .../test/resources/META-INF/persistence.xml | 12 +++- .../hsadmin/common/util/ReflectionUtil.java | 30 ++++++++ pom.xml | 6 ++ 12 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 cust-services/src/test/java/de/hsadmin/bo/customer/CustomerPackageBoPojoTest.java create mode 100644 cust-services/src/test/java/de/hsadmin/bo/customer/MemberShareTest.java create mode 100644 cust-services/src/test/java/de/hsadmin/bo/domain/DomainPackageBoTest.java create mode 100644 cust-services/src/test/java/de/hsadmin/bo/pac/PacPackageBoPojoTest.java create mode 100644 cust-services/src/test/java/de/hsadmin/test/PojoTestUtil.java diff --git a/cust-services/src/main/java/de/hsadmin/bo/customer/MemberShare.java b/cust-services/src/main/java/de/hsadmin/bo/customer/MemberShare.java index 8d825d6..73d0d12 100644 --- a/cust-services/src/main/java/de/hsadmin/bo/customer/MemberShare.java +++ b/cust-services/src/main/java/de/hsadmin/bo/customer/MemberShare.java @@ -90,5 +90,10 @@ public class MemberShare implements Serializable { public void setComment(String comment) { this.comment = comment; } - + + @Override + public String toString() { + return "MemberShare [id=" + id + ", customer=" + customer.getName() + ", date=" + date + ", action=" + action + + ", quantity=" + quantity + ", comment=" + comment + "]"; + } } diff --git a/cust-services/src/main/java/de/hsadmin/bo/domain/DomainOption.java b/cust-services/src/main/java/de/hsadmin/bo/domain/DomainOption.java index 9e84f0e..78aeb68 100644 --- a/cust-services/src/main/java/de/hsadmin/bo/domain/DomainOption.java +++ b/cust-services/src/main/java/de/hsadmin/bo/domain/DomainOption.java @@ -13,6 +13,8 @@ import javax.persistence.ManyToMany; import javax.persistence.SequenceGenerator; import javax.persistence.Table; +import org.apache.commons.lang3.StringUtils; + @Table(name="domain_option") @Entity(name="DomainOption") @SequenceGenerator(name = "DomainOptionSeqGen", sequenceName = "domain_option_id_seq") @@ -49,14 +51,14 @@ public class DomainOption { public boolean equals(Object obj) { if (obj instanceof DomainOption) { DomainOption opt = (DomainOption) obj; - return getName().equals(opt.getName()); + return StringUtils.equals(getName(), opt.getName()); } return false; } @Override public int hashCode() { - return getName().hashCode(); + return (getName()!=null ? getName() : "").hashCode(); } @Override diff --git a/cust-services/src/main/java/de/hsadmin/bo/pac/PacComponent.java b/cust-services/src/main/java/de/hsadmin/bo/pac/PacComponent.java index d15f8ba..c0601a9 100644 --- a/cust-services/src/main/java/de/hsadmin/bo/pac/PacComponent.java +++ b/cust-services/src/main/java/de/hsadmin/bo/pac/PacComponent.java @@ -95,7 +95,7 @@ public class PacComponent implements Serializable { @Override public String toString() { - return "pac=" + pac.getName() + ";comp=" + getBaseComponent().getFeature() + ";quantity=" + getQuantity(); + return "pac=" + (pac!=null?pac.getName():"") + ";comp=" + (getBaseComponent()!=null?getBaseComponent().getFeature():"") + ";quantity=" + getQuantity(); } } diff --git a/cust-services/src/test/java/de/hsadmin/bo/customer/CustomerPackageBoPojoTest.java b/cust-services/src/test/java/de/hsadmin/bo/customer/CustomerPackageBoPojoTest.java new file mode 100644 index 0000000..537b57d --- /dev/null +++ b/cust-services/src/test/java/de/hsadmin/bo/customer/CustomerPackageBoPojoTest.java @@ -0,0 +1,23 @@ +package de.hsadmin.bo.customer; + +import static de.hsadmin.test.PojoTestUtil.*; + +import org.junit.Test; + +import de.hsadmin.test.PojoTestUtil; + +public class CustomerPackageBoPojoTest { + + @Test + public void ensureProperSetterGetterImplementations() { + PojoTestUtil.ensureProperSetterGetterImplementations("de.hsadmin.bo.customer", + include(de.hsadmin.bo.customer.Contact.class), + include(de.hsadmin.bo.customer.Customer.class), + include(de.hsadmin.bo.customer.IndicatorVAT.class), + include(de.hsadmin.bo.customer.SEPADirectDebit.class), + include(de.hsadmin.bo.customer.MemberShare.class), + include(de.hsadmin.bo.customer.ShareAction.class), + include(de.hsadmin.bo.customer.MemberAsset.class), + include(de.hsadmin.bo.customer.AssetAction.class)); + } +} diff --git a/cust-services/src/test/java/de/hsadmin/bo/customer/MemberShareTest.java b/cust-services/src/test/java/de/hsadmin/bo/customer/MemberShareTest.java new file mode 100644 index 0000000..00c7b04 --- /dev/null +++ b/cust-services/src/test/java/de/hsadmin/bo/customer/MemberShareTest.java @@ -0,0 +1,36 @@ +package de.hsadmin.bo.customer; + + +import static org.junit.Assert.assertEquals; + +import org.joda.time.LocalDate; +import org.junit.Test; + +import de.hsadmin.dao.customer.CustomerDaoTest; +import de.hsadmin.test.JpaBasedTest; + +public class MemberShareTest extends JpaBasedTest { + + @Test + public void testMemberShareAgainstDatabase() { + // given + Customer customer = store(CustomerDaoTest.createNewCustomer(10001, "testCust")); + + // when + MemberShare newEntity = store(createNewMemberShare(customer)); + MemberShare foundEntity = getEM().find(MemberShare.class, newEntity.getId()); + + // then + assertEquals(newEntity.toString(), foundEntity.toString()); + } + + public static MemberShare createNewMemberShare(final Customer customer) { + MemberShare newEntity = new MemberShare(); + newEntity.setCustomer(customer); + newEntity.setAction(ShareAction.SUBSCRIPTION); + newEntity.setDate(new LocalDate(2017, 4, 13).toDate()); + newEntity.setQuantity(5); + newEntity.setComment("test comment"); + return newEntity; + } +} diff --git a/cust-services/src/test/java/de/hsadmin/bo/domain/DomainPackageBoTest.java b/cust-services/src/test/java/de/hsadmin/bo/domain/DomainPackageBoTest.java new file mode 100644 index 0000000..836dbc3 --- /dev/null +++ b/cust-services/src/test/java/de/hsadmin/bo/domain/DomainPackageBoTest.java @@ -0,0 +1,18 @@ +package de.hsadmin.bo.domain; + +import static de.hsadmin.test.PojoTestUtil.*; + +import org.junit.Test; + +import de.hsadmin.test.PojoTestUtil; + +public class DomainPackageBoTest { + + @Test + public void ensureProperSetterGetterImplementations() { + PojoTestUtil.ensureProperSetterGetterImplementations("de.hsadmin.bo.domain", + include(de.hsadmin.bo.domain.Domain.class), + include(de.hsadmin.bo.domain.DomainOption.class), + include(de.hsadmin.bo.domain.EMailAddress.class)); + } +} diff --git a/cust-services/src/test/java/de/hsadmin/bo/pac/PacPackageBoPojoTest.java b/cust-services/src/test/java/de/hsadmin/bo/pac/PacPackageBoPojoTest.java new file mode 100644 index 0000000..bf24b63 --- /dev/null +++ b/cust-services/src/test/java/de/hsadmin/bo/pac/PacPackageBoPojoTest.java @@ -0,0 +1,25 @@ +package de.hsadmin.bo.pac; + +import static de.hsadmin.test.PojoTestUtil.*; + +import org.junit.Test; + +import de.hsadmin.test.PojoTestUtil; + +public class PacPackageBoPojoTest { + + @Test + public void ensureProperSetterGetterImplementations() { + PojoTestUtil.ensureProperSetterGetterImplementations("de.hsadmin.bo.pac", + include(de.hsadmin.bo.pac.Hive.class), + include(de.hsadmin.bo.pac.BasePac.class), + include(de.hsadmin.bo.pac.Pac.class), + include(de.hsadmin.bo.pac.Component.class), + include(de.hsadmin.bo.pac.BaseComponent.class), + include(de.hsadmin.bo.pac.PacComponent.class), + include(de.hsadmin.bo.pac.EMailAlias.class), + include(de.hsadmin.bo.pac.UnixUser.class), + include(de.hsadmin.bo.pac.INetAddress.class), + exclude(de.hsadmin.bo.pac.PacEntityListener.class)); + } +} diff --git a/cust-services/src/test/java/de/hsadmin/dao/customer/CustomerDaoTest.java b/cust-services/src/test/java/de/hsadmin/dao/customer/CustomerDaoTest.java index 980f855..984774f 100644 --- a/cust-services/src/test/java/de/hsadmin/dao/customer/CustomerDaoTest.java +++ b/cust-services/src/test/java/de/hsadmin/dao/customer/CustomerDaoTest.java @@ -26,7 +26,7 @@ public class CustomerDaoTest extends JpaBasedTest { assertEquals(newCustomer.getId(), foundCustomer.getId()); } - private Customer createNewCustomer(int memberNo, String memberCode) { + public static Customer createNewCustomer(int memberNo, String memberCode) { Customer newCustomer = new Customer(); newCustomer.setMemberNo(memberNo); newCustomer.setName(memberCode); diff --git a/cust-services/src/test/java/de/hsadmin/test/PojoTestUtil.java b/cust-services/src/test/java/de/hsadmin/test/PojoTestUtil.java new file mode 100644 index 0000000..489d79c --- /dev/null +++ b/cust-services/src/test/java/de/hsadmin/test/PojoTestUtil.java @@ -0,0 +1,68 @@ +package de.hsadmin.test; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.PojoClassFilter; +import com.openpojo.reflection.filters.FilterChain; +import com.openpojo.reflection.filters.FilterClassName; +import com.openpojo.reflection.filters.FilterNestedClasses; +import com.openpojo.reflection.filters.FilterPackageInfo; +import com.openpojo.reflection.impl.PojoClassFactory; +import com.openpojo.validation.Validator; +import com.openpojo.validation.ValidatorBuilder; +import com.openpojo.validation.test.impl.GetterTester; +import com.openpojo.validation.test.impl.SetterTester; + +public class PojoTestUtil { + + public static void ensureProperSetterGetterImplementations(final String packageUnderTest, String... expectedClasseNames ) { + ensureExpectedClassesAreTested(packageUnderTest, Arrays.asList(expectedClasseNames) ); + + Validator validator = ValidatorBuilder.create() + // See com.openpojo.validation.test.impl for more ... + .with(new SetterTester()) + .with(new GetterTester()) + .build(); + validator.validate(packageUnderTest, new FilterPackageInfo()); + } + + public static String include(Class clazz) { + return clazz.getName(); + } + + public static String exclude(Class clazz) { + return clazz.getName(); + } + + private static void ensureExpectedClassesAreTested(final String packageUnderTest, final List expectedClassNames) { + Collections.sort(expectedClassNames); + List pojoClasseNames = new ArrayList(); + for ( PojoClass p: PojoClassFactory.getPojoClasses(packageUnderTest, + new FilterChain(new FilterPackageInfo(), new FilterNestedClasses(), new FilterInverse(new FilterClassName(".*Test$"))) ) ) { + pojoClasseNames.add( p.getClazz().getName() ); + } + Collections.sort(pojoClasseNames); + + assertEquals("precondition failed", expectedClassNames.toString().replaceAll(", ", "\n"), pojoClasseNames.toString().replaceAll(", ", "\n")); + } + + private static class FilterInverse implements PojoClassFilter { + + private PojoClassFilter delegate; + + public FilterInverse(PojoClassFilter delegate) { + this.delegate = delegate; + } + + @Override + public boolean include(PojoClass pojoClass) { + return !delegate.include(pojoClass); + } + } +} diff --git a/cust-services/src/test/resources/META-INF/persistence.xml b/cust-services/src/test/resources/META-INF/persistence.xml index 21a0ff5..ed38077 100644 --- a/cust-services/src/test/resources/META-INF/persistence.xml +++ b/cust-services/src/test/resources/META-INF/persistence.xml @@ -4,14 +4,24 @@ http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> org.apache.openjpa.persistence.PersistenceProviderImpl + de.hsadmin.bo.customer.Customer de.hsadmin.bo.customer.Contact de.hsadmin.bo.customer.SEPADirectDebit + de.hsadmin.bo.pac.INetAddress + de.hsadmin.bo.pac.Hive de.hsadmin.bo.pac.Pac + de.hsadmin.bo.pac.BasePac + de.hsadmin.bo.pac.Component + de.hsadmin.bo.pac.BaseComponent de.hsadmin.bo.pac.PacComponent de.hsadmin.bo.pac.UnixUser + de.hsadmin.bo.customer.MemberShare + de.hsadmin.bo.customer.MemberAsset + false + - + \ No newline at end of file diff --git a/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java b/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java index 33e7bb8..ecc4617 100644 --- a/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java +++ b/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java @@ -5,6 +5,11 @@ import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.commons.lang3.builder.EqualsBuilder; import de.hsadmin.common.error.TechnicalException; import de.hsadmin.common.error.UserError; @@ -62,4 +67,29 @@ public class ReflectionUtil { } } + public static Collection getDeclaredFieldNames(Class clazz) { + Field[] fields = clazz.getDeclaredFields(); + Collection fieldNames = new ArrayList(); + for ( Field f: fields ) { + if ( (f.getModifiers() & Modifier.STATIC) == 0 ) { + fieldNames.add(f.getName()); + } + } + return fieldNames; + } + + public static boolean reflectionEquals(Object o1, Object o2) { + Collection excludesFieldNames = new ArrayList(); + + // ignore generated fields, e.g. for OpenJPA proxies + if ( o1.getClass().isSynthetic() ) { + excludesFieldNames.addAll(ReflectionUtil.getDeclaredFieldNames(o1.getClass())); + } + ReflectionUtil.getDeclaredFieldNames(o2.getClass()); + if ( o2.getClass().isSynthetic() ) { + excludesFieldNames.addAll(ReflectionUtil.getDeclaredFieldNames(o2.getClass())); + } + return EqualsBuilder.reflectionEquals(o1, 2, excludesFieldNames); + } + } diff --git a/pom.xml b/pom.xml index 754efe0..017a123 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,12 @@ 4.12 test + + com.openpojo + openpojo + 0.8.4 + test + pl.pragmatists JUnitParams