From 2c82bd945096184309750ab212603fe16d20dad4 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 19 Dec 2015 13:17:28 +0100 Subject: [PATCH] Added tests for lazy-loading pattern --- .../lazy/loading/AbstractHolderTest.java | 41 +++++++++++++++ .../lazy/loading/HolderNaiveTest.java | 26 ++++++++++ .../lazy/loading/HolderThreadSafeTest.java | 51 ++++++------------- .../lazy/loading/Java8HolderTest.java | 40 +++++++++++++++ 4 files changed, 123 insertions(+), 35 deletions(-) create mode 100644 lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java create mode 100644 lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java create mode 100644 lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java new file mode 100644 index 000000000..99523cd0a --- /dev/null +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java @@ -0,0 +1,41 @@ +package com.iluwatar.lazy.loading; + +import org.junit.Test; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertSame; +import static junit.framework.TestCase.assertNull; + +/** + * Date: 12/19/15 - 11:58 AM + * + * @author Jeroen Meulemeester + */ +public abstract class AbstractHolderTest { + + /** + * Get the internal state of the holder value + * + * @return The internal value + */ + abstract Heavy getInternalHeavyValue() throws Exception; + + /** + * Request a lazy loaded {@link Heavy} object from the holder. + * + * @return The lazy loaded {@link Heavy} object + */ + abstract Heavy getHeavy() throws Exception; + + /** + * This test shows that the heavy field is not instantiated until the method getHeavy is called + */ + @Test(timeout = 3000) + public void testGetHeavy() throws Exception { + assertNull(getInternalHeavyValue()); + assertNotNull(getHeavy()); + assertNotNull(getInternalHeavyValue()); + assertSame(getHeavy(), getInternalHeavyValue()); + } + +} diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java new file mode 100644 index 000000000..2c539e8ca --- /dev/null +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java @@ -0,0 +1,26 @@ +package com.iluwatar.lazy.loading; + +import java.lang.reflect.Field; + +/** + * Date: 12/19/15 - 12:05 PM + * + * @author Jeroen Meulemeester + */ +public class HolderNaiveTest extends AbstractHolderTest { + + private final HolderNaive holder = new HolderNaive(); + + @Override + Heavy getInternalHeavyValue() throws Exception { + final Field holderField = HolderNaive.class.getDeclaredField("heavy"); + holderField.setAccessible(true); + return (Heavy) holderField.get(this.holder); + } + + @Override + Heavy getHeavy() { + return holder.getHeavy(); + } + +} \ No newline at end of file diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java index d827f186b..f6aed73b7 100644 --- a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java @@ -1,45 +1,26 @@ package com.iluwatar.lazy.loading; -import org.junit.Test; - import java.lang.reflect.Field; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - /** - * Using reflection this test shows that the heavy field is not instantiated until the method - * getHeavy is called + * Date: 12/19/15 - 12:19 PM * - * Created by jones on 11/10/2015. + * @author Jeroen Meulemeester */ -public class HolderThreadSafeTest { +public class HolderThreadSafeTest extends AbstractHolderTest { - @Test - public void test() throws IllegalAccessException { - HolderThreadSafe hts = new HolderThreadSafe(); + private final HolderThreadSafe holder = new HolderThreadSafe(); - { - // first call is null - Field[] ff = HolderThreadSafe.class.getDeclaredFields(); - for (Field f : ff) { - f.setAccessible(true); - } - - assertNull(ff[0].get(hts)); - } - - // now it is lazily loaded - hts.getHeavy(); - - { - // now it is not null - call via reflection so that the test is the same before and after - Field[] ff = HolderThreadSafe.class.getDeclaredFields(); - for (Field f : ff) { - f.setAccessible(true); - } - - assertNotNull(ff[0].get(hts)); - } + @Override + Heavy getInternalHeavyValue() throws Exception { + final Field holderField = HolderThreadSafe.class.getDeclaredField("heavy"); + holderField.setAccessible(true); + return (Heavy) holderField.get(this.holder); } -} + + @Override + Heavy getHeavy() throws Exception { + return this.holder.getHeavy(); + } + +} \ No newline at end of file diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java new file mode 100644 index 000000000..aed9a054e --- /dev/null +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java @@ -0,0 +1,40 @@ +package com.iluwatar.lazy.loading; + +import java.lang.reflect.Field; +import java.util.function.Supplier; + +/** + * Date: 12/19/15 - 12:27 PM + * + * @author Jeroen Meulemeester + */ +public class Java8HolderTest extends AbstractHolderTest { + + private final Java8Holder holder = new Java8Holder(); + + + @Override + Heavy getInternalHeavyValue() throws Exception { + final Field holderField = Java8Holder.class.getDeclaredField("heavy"); + holderField.setAccessible(true); + + final Supplier supplier = (Supplier) holderField.get(this.holder); + final Class supplierClass = supplier.getClass(); + + // This is a little fishy, but I don't know another way to test this: + // The lazy holder is at first a lambda, but gets replaced with a new supplier after loading ... + if (supplierClass.isLocalClass()) { + final Field instanceField = supplierClass.getDeclaredField("heavyInstance"); + instanceField.setAccessible(true); + return (Heavy) instanceField.get(supplier); + } else { + return null; + } + } + + @Override + Heavy getHeavy() throws Exception { + return holder.getHeavy(); + } + +} \ No newline at end of file