-
-
Save menelaosbgr/72b5a799215f026daff5eda31c9d24be to your computer and use it in GitHub Desktop.
JUnit test for 100% code coverage of Lombok's @DaTa annotation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.reflect.ClassPath; | |
import javassist.CannotCompileException; | |
import javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
import javassist.CtMethod; | |
import javassist.CtNewConstructor; | |
import javassist.CtNewMethod; | |
import javassist.NotFoundException; | |
import nl.jqno.equalsverifier.EqualsVerifier; | |
import nl.jqno.equalsverifier.Warning; | |
import org.junit.Assert; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.meanbean.test.BeanTestException; | |
import org.meanbean.test.BeanTester; | |
import java.io.IOException; | |
import java.lang.reflect.Modifier; | |
// ClassLoader code adapted from http://stackoverflow.com/a/21430849/2464657 | |
public class ModelTests { | |
private static final String MODEL_PACKAGE = "my.package"; | |
private BeanTester beanTester; | |
@Before | |
public void before() { | |
beanTester = new BeanTester(); | |
} | |
@Test | |
public void testAbstractModels() throws IllegalArgumentException, BeanTestException, InstantiationException, | |
IllegalAccessException, IOException, AssertionError, NotFoundException, CannotCompileException { | |
// Loop through classes in the model package | |
final ClassLoader loader = Thread.currentThread().getContextClassLoader(); | |
for (final ClassPath.ClassInfo info : ClassPath.from(loader).getTopLevelClassesRecursive(MODEL_PACKAGE)) { | |
final Class<?> clazz = info.load(); | |
// Only test abstract classes | |
if (Modifier.isAbstract(clazz.getModifiers())) { | |
// Test #equals and #hashCode | |
EqualsVerifier.forClass(clazz).suppress(Warning.STRICT_INHERITANCE, Warning.NONFINAL_FIELDS).verify(); | |
} | |
} | |
} | |
@Test | |
public void testConcreteModels() | |
throws IOException, InstantiationException, IllegalAccessException, NotFoundException, CannotCompileException { | |
// Loop through classes in the model package | |
final ClassLoader loader = Thread.currentThread().getContextClassLoader(); | |
for (final ClassPath.ClassInfo info : ClassPath.from(loader).getTopLevelClassesRecursive(MODEL_PACKAGE)) { | |
final Class<?> clazz = info.load(); | |
// Skip abstract classes, interfaces and this class. | |
int modifiers = clazz.getModifiers(); | |
if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers) || clazz.equals(this.getClass())) { | |
continue; | |
} | |
// Test getters, setters and #toString | |
beanTester.testBean(clazz); | |
// Test #equals and #hashCode | |
EqualsVerifier.forClass(clazz).withRedefinedSuperclass() | |
.suppress(Warning.STRICT_INHERITANCE, Warning.NONFINAL_FIELDS).verify(); | |
// Verify not equals with subclass (for code coverage with Lombok) | |
Assert.assertFalse(clazz.newInstance().equals(createSubClassInstance(clazz.getName()))); | |
} | |
} | |
// Adapted from http://stackoverflow.com/questions/17259421/java-creating-a-subclass-dynamically | |
static Object createSubClassInstance(String superClassName) | |
throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException { | |
ClassPool pool = ClassPool.getDefault(); | |
// Create the class. | |
CtClass subClass = pool.makeClass(superClassName + "Extended"); | |
final CtClass superClass = pool.get(superClassName); | |
subClass.setSuperclass(superClass); | |
subClass.setModifiers(Modifier.PUBLIC); | |
// Add a constructor which will call super( ... ); | |
CtClass[] params = new CtClass[] {}; | |
final CtConstructor ctor = CtNewConstructor.make(params, null, CtNewConstructor.PASS_PARAMS, null, null, subClass); | |
subClass.addConstructor(ctor); | |
// Add a canEquals method | |
final CtMethod ctmethod = CtNewMethod | |
.make("public boolean canEqual(Object o) { return o instanceof " + superClassName + "Extended; }", subClass); | |
subClass.addMethod(ctmethod); | |
return subClass.toClass().newInstance(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment