
org.ligoj.bootstrap.model.AbstractBusinessEntityTest Maven / Gradle / Ivy
/*
* Licensed under MIT (https://github.com/ligoj/ligoj/blob/master/LICENSE)
*/
package org.ligoj.bootstrap.model;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.jupiter.api.Assertions;
import org.mockito.Mockito;
import jodd.bean.BeanUtil;
/**
* Test business keyed entities basic ORM operations : hash code and equals.
*/
public abstract class AbstractBusinessEntityTest {
/**
* Bean utility.
*/
private static final BeanUtil BEAN_UTIL = BeanUtil.declaredSilent;
/**
* Test equals and hash code operation with all possible combinations
*
* @param modelClass the entity to test.
* @param The type of the entity to test.
* @throws ReflectiveOperationException Due to reflection.
*/
protected void testEqualsAndHash(final Class modelClass) throws ReflectiveOperationException {
testEqualsAndHash(modelClass, "id");
}
/**
* Test equals and hash code operation with all possible combinations
*
* @param modelClass the entity to test.
* @param idProperties the list of business key parts.
* @param The type of the entity to test.
* @throws ReflectiveOperationException due to reflection.
*/
protected void testEqualsAndHash(final Class modelClass, final String... idProperties)
throws ReflectiveOperationException {
final var systemUser = modelClass.getDeclaredConstructor().newInstance();
final var systemUser2 = modelClass.getDeclaredConstructor().newInstance();
Assertions.assertFalse(systemUser.equals(null)); // NOPMD NOSONAR -- for coverage
Assertions.assertEquals(systemUser, systemUser);
Assertions.assertEquals(systemUser, systemUser2);
Assertions.assertFalse(systemUser.equals(1));
Assertions.assertNotSame(0, systemUser.hashCode());
// Get all identifier combinations
final var combinations = combinations(idProperties);
// For each, compute equality and hash code
testCombinations(modelClass, combinations);
// Test inheritance "canEqual" if available (as Scala)
final var mockCanEqual = Mockito.mock(modelClass);
systemUser.equals(mockCanEqual);
}
private void setValues(final T beanValued, final List combination) {
for (final var propertyString : combination) {
BEAN_UTIL.setProperty(beanValued, propertyString, 1);
}
}
private void testCombinations(final Class modelClass, final List> combinations)
throws ReflectiveOperationException {
for (final var combination : combinations) {
final var beanValued = modelClass.getDeclaredConstructor().newInstance();
setValues(beanValued, combination);
testCombinations(modelClass, combinations, combination, beanValued);
Assertions.assertNotSame(0, beanValued.hashCode());
}
}
/**
* Test the given combinations.
*/
private void testCombinations(final Class modelClass, final List> combinations,
final List combination, final T beanValued) throws ReflectiveOperationException {
for (final var properties : combinations) {
testCombination(modelClass, combination, beanValued, properties);
}
}
/**
* Test the given combination.
*/
private void testCombination(final Class modelClass, final List combination, final T beanValued,
final List properties) throws ReflectiveOperationException {
final var beanValued2 = modelClass.getDeclaredConstructor().newInstance();
setValues(beanValued2, properties);
Assertions.assertEquals(properties.equals(combination), beanValued.equals(beanValued2));
}
/**
* Generates all combinations and returns them in a list of lists.
*/
private List> combinations(final String... array) {
final long count = 2L << array.length - 1;
final List> totalCombinations = new LinkedList<>();
for (var i = 0; i < count; i++) {
final List combinations = new LinkedList<>();
addPropertyCombinations(i, combinations, array);
totalCombinations.add(combinations);
}
return totalCombinations;
}
private void addPropertyCombinations(final int i, final List combinations, final String... array) {
for (var j = 0; j < array.length; j++) {
if ((i & (1 << j)) != 0) {
combinations.add(array[j]);
}
}
}
/**
* Simple POJO utility getter/setter for POJO compliance.
*
* @param pojo The POJO class.
* @return The POJO instance with all setters called.
* @param POJO type.
* @throws ReflectiveOperationException When reflects fails.
*/
protected T testPojo(Class pojo) throws ReflectiveOperationException {
var bean = pojo.getConstructor().newInstance();
for (final var field : FieldUtils.getAllFields(pojo)) {
if (field.getName().contains("$") || Modifier.isStatic(field.getModifiers())) {
continue;
}
final var setter = "set" + StringUtils.capitalize(field.getName());
var getter = "get" + StringUtils.capitalize(field.getName());
Object param = null;
var type = field.getType();
if (type.equals(double.class)) {
param = 0D;
} else if (type.equals(boolean.class)) {
getter = "is" + StringUtils.capitalize(field.getName());
param = false;
}
pojo.getMethod(setter, type).invoke(bean, param);
pojo.getMethod(getter).invoke(bean);
}
return bean;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy