Merge pull request #331 from fluxw42/master

Add unit tests for remaining patterns
This commit is contained in:
Ilkka Seppälä 2016-01-01 18:24:58 +02:00
commit 30e09a8dd9
111 changed files with 4413 additions and 134 deletions

View File

@ -0,0 +1,29 @@
package com.iluwatar.multiton;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
/**
* Date: 12/22/15 - 22:28 AM
*
* @author Jeroen Meulemeester
*/
public class NazgulTest {
/**
* Verify if {@link Nazgul#getInstance(NazgulName)} returns the correct Nazgul multiton instance
*/
@Test
public void testGetInstance() {
for (final NazgulName name : NazgulName.values()) {
final Nazgul nazgul = Nazgul.getInstance(name);
assertNotNull(nazgul);
assertSame(nazgul, Nazgul.getInstance(name));
assertEquals(name, nazgul.getName());
}
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,43 @@
package com.iluwatar.nullobject;
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
/**
* Date: 12/26/15 - 11:47 PM
*
* @author Jeroen Meulemeester
*/
public class NullNodeTest extends StdOutTest {
/**
* Verify if {@link NullNode#getInstance()} actually returns the same object instance
*/
@Test
public void testGetInstance() {
final NullNode instance = NullNode.getInstance();
assertNotNull(instance);
assertSame(instance, NullNode.getInstance());
}
@Test
public void testFields() {
final NullNode node = NullNode.getInstance();
assertEquals(0, node.getTreeSize());
assertNull(node.getName());
assertNull(node.getLeft());
assertNull(node.getRight());
}
@Test
public void testWalk() throws Exception {
NullNode.getInstance().walk();
Mockito.verifyZeroInteractions(getStdOutMock());
}
}

View File

@ -0,0 +1,54 @@
package com.iluwatar.nullobject;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since walking through the tree has no
* influence on any other accessible object, except for writing to std-out using {@link
* System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,101 @@
package com.iluwatar.nullobject;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
/**
* Date: 12/26/15 - 11:44 PM
*
* @author Jeroen Meulemeester
*/
public class TreeTest extends StdOutTest {
/**
* During the tests, the same tree structure will be used, shown below. End points will be
* terminated with the {@link NullNode} instance.
*
* <pre>
* root
* level1_a
*    level2_a
*       level3_a
*       level3_b
*    level2_b
* level1_b
* </pre>
*/
private static final Node TREE_ROOT;
static {
final NodeImpl level1B = new NodeImpl("level1_b", NullNode.getInstance(), NullNode.getInstance());
final NodeImpl level2B = new NodeImpl("level2_b", NullNode.getInstance(), NullNode.getInstance());
final NodeImpl level3A = new NodeImpl("level3_a", NullNode.getInstance(), NullNode.getInstance());
final NodeImpl level3B = new NodeImpl("level3_b", NullNode.getInstance(), NullNode.getInstance());
final NodeImpl level2A = new NodeImpl("level2_a", level3A, level3B);
final NodeImpl level1A = new NodeImpl("level1_a", level2A, level2B);
TREE_ROOT = new NodeImpl("root", level1A, level1B);
}
/**
* Verify the number of items in the tree. The root has 6 children so we expect a {@link
* Node#getTreeSize()} of 7 {@link Node}s in total.
*/
@Test
public void testTreeSize() {
assertEquals(7, TREE_ROOT.getTreeSize());
}
/**
* Walk through the tree and verify if every item is handled
*/
@Test
public void testWalk() {
TREE_ROOT.walk();
final InOrder inOrder = Mockito.inOrder(getStdOutMock());
inOrder.verify(getStdOutMock()).println("root");
inOrder.verify(getStdOutMock()).println("level1_a");
inOrder.verify(getStdOutMock()).println("level2_a");
inOrder.verify(getStdOutMock()).println("level3_a");
inOrder.verify(getStdOutMock()).println("level3_b");
inOrder.verify(getStdOutMock()).println("level2_b");
inOrder.verify(getStdOutMock()).println("level1_b");
inOrder.verifyNoMoreInteractions();
}
@Test
public void testGetLeft() throws Exception {
final Node level1 = TREE_ROOT.getLeft();
assertNotNull(level1);
assertEquals("level1_a", level1.getName());
assertEquals(5, level1.getTreeSize());
final Node level2 = level1.getLeft();
assertNotNull(level2);
assertEquals("level2_a", level2.getName());
assertEquals(3, level2.getTreeSize());
final Node level3 = level2.getLeft();
assertNotNull(level3);
assertEquals("level3_a", level3.getName());
assertEquals(1, level3.getTreeSize());
assertSame(NullNode.getInstance(), level3.getRight());
assertSame(NullNode.getInstance(), level3.getLeft());
}
@Test
public void testGetRight() throws Exception {
final Node level1 = TREE_ROOT.getRight();
assertNotNull(level1);
assertEquals("level1_b", level1.getName());
assertEquals(1, level1.getTreeSize());
assertSame(NullNode.getInstance(), level1.getRight());
assertSame(NullNode.getInstance(), level1.getLeft());
}
}

View File

@ -0,0 +1,99 @@
package com.iluwatar.object.pool;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* Date: 12/27/15 - 1:05 AM
*
* @author Jeroen Meulemeester
*/
public class OliphauntPoolTest {
/**
* Use the same object 100 times subsequently. This should not take much time since the heavy
* object instantiation is done only once. Verify if we get the same object each time.
*/
@Test(timeout = 5000)
public void testSubsequentCheckinCheckout() {
final OliphauntPool pool = new OliphauntPool();
assertEquals(pool.toString(), "Pool available=0 inUse=0");
final Oliphaunt expectedOliphaunt = pool.checkOut();
assertEquals(pool.toString(), "Pool available=0 inUse=1");
pool.checkIn(expectedOliphaunt);
assertEquals(pool.toString(), "Pool available=1 inUse=0");
for (int i = 0; i < 100; i++) {
final Oliphaunt oliphaunt = pool.checkOut();
assertEquals(pool.toString(), "Pool available=0 inUse=1");
assertSame(expectedOliphaunt, oliphaunt);
assertEquals(expectedOliphaunt.getId(), oliphaunt.getId());
assertEquals(expectedOliphaunt.toString(), oliphaunt.toString());
pool.checkIn(oliphaunt);
assertEquals(pool.toString(), "Pool available=1 inUse=0");
}
}
/**
* Use the same object 100 times subsequently. This should not take much time since the heavy
* object instantiation is done only once. Verify if we get the same object each time.
*/
@Test(timeout = 5000)
public void testConcurrentCheckinCheckout() {
final OliphauntPool pool = new OliphauntPool();
assertEquals(pool.toString(), "Pool available=0 inUse=0");
final Oliphaunt firstOliphaunt = pool.checkOut();
assertEquals(pool.toString(), "Pool available=0 inUse=1");
final Oliphaunt secondOliphaunt = pool.checkOut();
assertEquals(pool.toString(), "Pool available=0 inUse=2");
assertNotSame(firstOliphaunt, secondOliphaunt);
assertEquals(firstOliphaunt.getId() + 1, secondOliphaunt.getId());
// After checking in the second, we should get the same when checking out a new oliphaunt ...
pool.checkIn(secondOliphaunt);
assertEquals(pool.toString(), "Pool available=1 inUse=1");
final Oliphaunt oliphaunt3 = pool.checkOut();
assertEquals(pool.toString(), "Pool available=0 inUse=2");
assertSame(secondOliphaunt, oliphaunt3);
// ... and the same applies for the first one
pool.checkIn(firstOliphaunt);
assertEquals(pool.toString(), "Pool available=1 inUse=1");
final Oliphaunt oliphaunt4 = pool.checkOut();
assertEquals(pool.toString(), "Pool available=0 inUse=2");
assertSame(firstOliphaunt, oliphaunt4);
// When both oliphaunt return to the pool, we should still get the same instances
pool.checkIn(firstOliphaunt);
assertEquals(pool.toString(), "Pool available=1 inUse=1");
pool.checkIn(secondOliphaunt);
assertEquals(pool.toString(), "Pool available=2 inUse=0");
// The order of the returned instances is not determined, so just put them in a list
// and verify if both expected instances are in there.
final List<Oliphaunt> oliphaunts = Arrays.asList(pool.checkOut(), pool.checkOut());
assertEquals(pool.toString(), "Pool available=0 inUse=2");
assertTrue(oliphaunts.contains(firstOliphaunt));
assertTrue(oliphaunts.contains(secondOliphaunt));
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -22,6 +22,10 @@ public abstract class Observable<S extends Observable<S, O, A>, O extends Observ
this.observers.add(observer);
}
public void removeObserver(O observer) {
this.observers.remove(observer);
}
/**
* Notify observers
*/

View File

@ -0,0 +1,37 @@
package com.iluwatar.observer;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Collection;
/**
* Date: 12/27/15 - 12:07 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class HobbitsTest extends WeatherObserverTest<Hobbits> {
@Parameterized.Parameters
public static Collection<Object[]> data() {
final ArrayList<Object[]> testData = new ArrayList<>();
testData.add(new Object[]{WeatherType.SUNNY, "The happy hobbits bade in the warm sun."});
testData.add(new Object[]{WeatherType.RAINY, "The hobbits look for cover from the rain."});
testData.add(new Object[]{WeatherType.WINDY, "The hobbits hold their hats tightly in the windy weather."});
testData.add(new Object[]{WeatherType.COLD, "The hobbits are shivering in the cold weather."});
return testData;
}
/**
* Create a new test with the given weather and expected response
*
* @param weather The weather that should be unleashed on the observer
* @param response The expected response from the observer
*/
public HobbitsTest(final WeatherType weather, final String response) {
super(weather, response, Hobbits::new);
}
}

View File

@ -0,0 +1,37 @@
package com.iluwatar.observer;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Collection;
/**
* Date: 12/27/15 - 12:07 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class OrcsTest extends WeatherObserverTest<Orcs> {
@Parameterized.Parameters
public static Collection<Object[]> data() {
final ArrayList<Object[]> testData = new ArrayList<>();
testData.add(new Object[]{WeatherType.SUNNY, "The sun hurts the orcs' eyes."});
testData.add(new Object[]{WeatherType.RAINY, "The orcs are dripping wet."});
testData.add(new Object[]{WeatherType.WINDY, "The orc smell almost vanishes in the wind."});
testData.add(new Object[]{WeatherType.COLD, "The orcs are freezing cold."});
return testData;
}
/**
* Create a new test with the given weather and expected response
*
* @param weather The weather that should be unleashed on the observer
* @param response The expected response from the observer
*/
public OrcsTest(final WeatherType weather, final String response) {
super(weather, response, Orcs::new);
}
}

View File

@ -0,0 +1,54 @@
package com.iluwatar.observer;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/27/15 - 12:16 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since changes in the weather doesn't has
* any influence on any other accessible objects, except for writing to std-out using {@link
* System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
protected final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,59 @@
package com.iluwatar.observer;
import org.junit.Test;
import java.util.function.Supplier;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/27/15 - 11:44 AM
*
* @author Jeroen Meulemeester
*/
public abstract class WeatherObserverTest<O extends WeatherObserver> extends StdOutTest {
/**
* The observer instance factory
*/
private final Supplier<O> factory;
/**
* The weather type currently tested
*/
private final WeatherType weather;
/**
* The expected response from the observer
*/
private final String response;
/**
* Create a new test instance using the given parameters
*
* @param weather The weather currently being tested
* @param response The expected response from the observer
* @param factory The factory, used to create an instance of the tested observer
*/
WeatherObserverTest(final WeatherType weather, final String response, final Supplier<O> factory) {
this.weather = weather;
this.response = response;
this.factory = factory;
}
/**
* Verify if the weather has the expected influence on the observer
*/
@Test
public void testObserver() {
final O observer = this.factory.get();
verifyZeroInteractions(getStdOutMock());
observer.update(this.weather);
verify(getStdOutMock()).println(this.response);
verifyNoMoreInteractions(getStdOutMock());
}
}

View File

@ -0,0 +1,61 @@
package com.iluwatar.observer;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/27/15 - 11:08 AM
*
* @author Jeroen Meulemeester
*/
public class WeatherTest extends StdOutTest {
/**
* Add a {@link WeatherObserver}, verify if it gets notified of a weather change, remove the
* observer again and verify that there are no more notifications.
*/
@Test
public void testAddRemoveObserver() {
final WeatherObserver observer = mock(WeatherObserver.class);
final Weather weather = new Weather();
weather.addObserver(observer);
verifyZeroInteractions(observer);
weather.timePasses();
verify(getStdOutMock()).println("The weather changed to rainy.");
verify(observer).update(WeatherType.RAINY);
weather.removeObserver(observer);
weather.timePasses();
verify(getStdOutMock()).println("The weather changed to windy.");
verifyNoMoreInteractions(observer, getStdOutMock());
}
/**
* Verify if the weather passes in the order of the {@link WeatherType}s
*/
@Test
public void testTimePasses() {
final WeatherObserver observer = mock(WeatherObserver.class);
final Weather weather = new Weather();
weather.addObserver(observer);
final InOrder inOrder = inOrder(observer, getStdOutMock());
final WeatherType[] weatherTypes = WeatherType.values();
for (int i = 1; i < 20; i++) {
weather.timePasses();
inOrder.verify(observer).update(weatherTypes[i % weatherTypes.length]);
}
verifyNoMoreInteractions(observer);
}
}

View File

@ -0,0 +1,41 @@
package com.iluwatar.observer.generic;
import com.iluwatar.observer.Hobbits;
import com.iluwatar.observer.WeatherObserverTest;
import com.iluwatar.observer.WeatherType;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Collection;
/**
* Date: 12/27/15 - 12:07 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class GHobbitsTest extends ObserverTest<GHobbits> {
@Parameterized.Parameters
public static Collection<Object[]> data() {
final ArrayList<Object[]> testData = new ArrayList<>();
testData.add(new Object[]{WeatherType.SUNNY, "The happy hobbits bade in the warm sun."});
testData.add(new Object[]{WeatherType.RAINY, "The hobbits look for cover from the rain."});
testData.add(new Object[]{WeatherType.WINDY, "The hobbits hold their hats tightly in the windy weather."});
testData.add(new Object[]{WeatherType.COLD, "The hobbits are shivering in the cold weather."});
return testData;
}
/**
* Create a new test with the given weather and expected response
*
* @param weather The weather that should be unleashed on the observer
* @param response The expected response from the observer
*/
public GHobbitsTest(final WeatherType weather, final String response) {
super(weather, response, GHobbits::new);
}
}

View File

@ -0,0 +1,65 @@
package com.iluwatar.observer.generic;
import com.iluwatar.observer.StdOutTest;
import com.iluwatar.observer.WeatherObserver;
import com.iluwatar.observer.WeatherType;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/27/15 - 11:08 AM
*
* @author Jeroen Meulemeester
*/
public class GWeatherTest extends StdOutTest {
/**
* Add a {@link WeatherObserver}, verify if it gets notified of a weather change, remove the
* observer again and verify that there are no more notifications.
*/
@Test
public void testAddRemoveObserver() {
final Race observer = mock(Race.class);
final GWeather weather = new GWeather();
weather.addObserver(observer);
verifyZeroInteractions(observer);
weather.timePasses();
verify(getStdOutMock()).println("The weather changed to rainy.");
verify(observer).update(weather, WeatherType.RAINY);
weather.removeObserver(observer);
weather.timePasses();
verify(getStdOutMock()).println("The weather changed to windy.");
verifyNoMoreInteractions(observer, getStdOutMock());
}
/**
* Verify if the weather passes in the order of the {@link WeatherType}s
*/
@Test
public void testTimePasses() {
final Race observer = mock(Race.class);
final GWeather weather = new GWeather();
weather.addObserver(observer);
final InOrder inOrder = inOrder(observer, getStdOutMock());
final WeatherType[] weatherTypes = WeatherType.values();
for (int i = 1; i < 20; i++) {
weather.timePasses();
inOrder.verify(observer).update(weather, weatherTypes[i % weatherTypes.length]);
}
verifyNoMoreInteractions(observer);
}
}

View File

@ -0,0 +1,62 @@
package com.iluwatar.observer.generic;
import com.iluwatar.observer.StdOutTest;
import com.iluwatar.observer.WeatherType;
import org.junit.Test;
import java.util.function.Supplier;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/27/15 - 11:44 AM
*
* @author Jeroen Meulemeester
*/
public abstract class ObserverTest<O extends Observer> extends StdOutTest {
/**
* The observer instance factory
*/
private final Supplier<O> factory;
/**
* The weather type currently tested
*/
private final WeatherType weather;
/**
* The expected response from the observer
*/
private final String response;
/**
* Create a new test instance using the given parameters
*
* @param weather The weather currently being tested
* @param response The expected response from the observer
* @param factory The factory, used to create an instance of the tested observer
*/
ObserverTest(final WeatherType weather, final String response, final Supplier<O> factory) {
this.weather = weather;
this.response = response;
this.factory = factory;
}
/**
* Verify if the weather has the expected influence on the observer
*/
@Test
public void testObserver() {
final O observer = this.factory.get();
verifyZeroInteractions(getStdOutMock());
observer.update(null, this.weather);
verify(getStdOutMock()).println(this.response);
verifyNoMoreInteractions(getStdOutMock());
}
}

View File

@ -0,0 +1,39 @@
package com.iluwatar.observer.generic;
import com.iluwatar.observer.WeatherType;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Collection;
/**
* Date: 12/27/15 - 12:07 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class OrcsTest extends ObserverTest<GOrcs> {
@Parameterized.Parameters
public static Collection<Object[]> data() {
final ArrayList<Object[]> testData = new ArrayList<>();
testData.add(new Object[]{WeatherType.SUNNY, "The sun hurts the orcs' eyes."});
testData.add(new Object[]{WeatherType.RAINY, "The orcs are dripping wet."});
testData.add(new Object[]{WeatherType.WINDY, "The orc smell almost vanishes in the wind."});
testData.add(new Object[]{WeatherType.COLD, "The orcs are freezing cold."});
return testData;
}
/**
* Create a new test with the given weather and expected response
*
* @param weather The weather that should be unleashed on the observer
* @param response The expected response from the observer
*/
public OrcsTest(final WeatherType weather, final String response) {
super(weather, response, GOrcs::new);
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,56 @@
package com.iluwatar.poison.pill;
import org.junit.Test;
import org.mockito.InOrder;
import java.time.LocalDateTime;
import static org.mockito.Mockito.inOrder;
/**
* Date: 12/27/15 - 9:45 PM
*
* @author Jeroen Meulemeester
*/
public class ConsumerTest extends StdOutTest {
@Test
public void testConsume() throws Exception {
final Message[] messages = new Message[]{
createMessage("you", "Hello!"),
createMessage("me", "Hi!"),
Message.POISON_PILL,
createMessage("late_for_the_party", "Hello? Anyone here?"),
};
final MessageQueue queue = new SimpleMessageQueue(messages.length);
for (final Message message : messages) {
queue.put(message);
}
new Consumer("NSA", queue).consume();
final InOrder inOrder = inOrder(getStdOutMock());
inOrder.verify(getStdOutMock()).println("Message [Hello!] from [you] received by [NSA]");
inOrder.verify(getStdOutMock()).println("Message [Hi!] from [me] received by [NSA]");
inOrder.verify(getStdOutMock()).println("Consumer NSA receive request to terminate.");
inOrder.verifyNoMoreInteractions();
}
/**
* Create a new message from the given sender with the given message body
*
* @param sender The sender's name
* @param message The message body
* @return The message instance
*/
private static Message createMessage(final String sender, final String message) {
final SimpleMessage msg = new SimpleMessage();
msg.addHeader(Message.Headers.SENDER, sender);
msg.addHeader(Message.Headers.DATE, LocalDateTime.now().toString());
msg.setBody(message);
return msg;
}
}

View File

@ -0,0 +1,40 @@
package com.iluwatar.poison.pill;
import org.junit.Test;
import static com.iluwatar.poison.pill.Message.Headers;
import static com.iluwatar.poison.pill.Message.POISON_PILL;
/**
* Date: 12/27/15 - 10:30 PM
*
* @author Jeroen Meulemeester
*/
public class PoisonMessageTest {
@Test(expected = UnsupportedOperationException.class)
public void testAddHeader() throws Exception {
POISON_PILL.addHeader(Headers.SENDER, "sender");
}
@Test(expected = UnsupportedOperationException.class)
public void testGetHeader() throws Exception {
POISON_PILL.getHeader(Headers.SENDER);
}
@Test(expected = UnsupportedOperationException.class)
public void testGetHeaders() throws Exception {
POISON_PILL.getHeaders();
}
@Test(expected = UnsupportedOperationException.class)
public void testSetBody() throws Exception {
POISON_PILL.setBody("Test message.");
}
@Test(expected = UnsupportedOperationException.class)
public void testGetBody() throws Exception {
POISON_PILL.getBody();
}
}

View File

@ -0,0 +1,64 @@
package com.iluwatar.poison.pill;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/27/15 - 10:32 PM
*
* @author Jeroen Meulemeester
*/
public class ProducerTest {
@Test
public void testSend() throws Exception {
final MqPublishPoint publishPoint = mock(MqPublishPoint.class);
final Producer producer = new Producer("producer", publishPoint);
verifyZeroInteractions(publishPoint);
producer.send("Hello!");
final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(publishPoint).put(messageCaptor.capture());
final Message message = messageCaptor.getValue();
assertNotNull(message);
assertEquals("producer", message.getHeader(Message.Headers.SENDER));
assertNotNull(message.getHeader(Message.Headers.DATE));
assertEquals("Hello!", message.getBody());
verifyNoMoreInteractions(publishPoint);
}
@Test
public void testStop() throws Exception {
final MqPublishPoint publishPoint = mock(MqPublishPoint.class);
final Producer producer = new Producer("producer", publishPoint);
verifyZeroInteractions(publishPoint);
producer.stop();
verify(publishPoint).put(eq(Message.POISON_PILL));
try {
producer.send("Hello!");
fail("Expected 'IllegalStateException' at this point, since the producer has stopped!");
} catch (IllegalStateException e) {
assertNotNull(e);
assertNotNull(e.getMessage());
assertEquals("Producer Hello! was stopped and fail to deliver requested message [producer].",
e.getMessage());
}
verifyNoMoreInteractions(publishPoint);
}
}

View File

@ -0,0 +1,40 @@
package com.iluwatar.poison.pill;
import org.junit.Test;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Date: 12/27/15 - 10:25 PM
*
* @author Jeroen Meulemeester
*/
public class SimpleMessageTest {
@Test
public void testGetHeaders() {
final SimpleMessage message = new SimpleMessage();
assertNotNull(message.getHeaders());
assertTrue(message.getHeaders().isEmpty());
final String senderName = "test";
message.addHeader(Message.Headers.SENDER, senderName);
assertNotNull(message.getHeaders());
assertFalse(message.getHeaders().isEmpty());
assertEquals(senderName, message.getHeaders().get(Message.Headers.SENDER));
}
@Test(expected = UnsupportedOperationException.class)
public void testUnModifiableHeaders() {
final SimpleMessage message = new SimpleMessage();
final Map<Message.Headers, String> headers = message.getHeaders();
headers.put(Message.Headers.SENDER, "test");
}
}

View File

@ -0,0 +1,53 @@
package com.iluwatar.poison.pill;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,52 @@
package com.iluwatar.privateclassdata;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
/**
* Date: 12/27/15 - 10:46 PM
*
* @author Jeroen Meulemeester
*/
public class ImmutableStewTest extends StdOutTest {
/**
* Verify if mixing the stew doesn't change the internal state
*/
@Test
public void testMix() {
final Stew stew = new Stew(1, 2, 3, 4);
final String message = "Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers";
final InOrder inOrder = inOrder(getStdOutMock());
for (int i = 0; i < 20; i++) {
stew.mix();
inOrder.verify(getStdOutMock()).println(message);
}
inOrder.verifyNoMoreInteractions();
}
/**
* Verify if tasting the stew actually removes one of each ingredient
*/
@Test
public void testDrink() {
final Stew stew = new Stew(1, 2, 3, 4);
stew.mix();
verify(getStdOutMock())
.println("Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers");
stew.taste();
verify(getStdOutMock()).println("Tasting the stew");
stew.mix();
verify(getStdOutMock())
.println("Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers");
}
}

View File

@ -0,0 +1,53 @@
package com.iluwatar.privateclassdata;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,33 @@
package com.iluwatar.privateclassdata;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
/**
* Date: 12/27/15 - 10:46 PM
*
* @author Jeroen Meulemeester
*/
public class StewTest extends StdOutTest {
/**
* Verify if mixing the stew doesn't change the internal state
*/
@Test
public void testMix() {
final ImmutableStew stew = new ImmutableStew(1, 2, 3, 4);
final String expectedMessage = "Mixing the immutable stew we find: 1 potatoes, "
+ "2 carrots, 3 meat and 4 peppers";
final InOrder inOrder = inOrder(getStdOutMock());
for (int i = 0; i < 20; i++) {
stew.mix();
inOrder.verify(getStdOutMock()).println(expectedMessage);
}
inOrder.verifyNoMoreInteractions();
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package com.iluwatar.producer.consumer;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
/**
* Date: 12/27/15 - 11:01 PM
*
* @author Jeroen Meulemeester
*/
public class ConsumerTest extends StdOutTest {
private static final int ITEM_COUNT = 5;
@Test
public void testConsume() throws Exception {
final ItemQueue queue = spy(new ItemQueue());
for (int id = 0; id < ITEM_COUNT; id++) {
queue.put(new Item("producer", id));
}
reset(queue); // Don't count the preparation above as interactions with the queue
final Consumer consumer = new Consumer("consumer", queue);
final InOrder inOrder = inOrder(getStdOutMock());
for (int id = 0; id < ITEM_COUNT; id++) {
consumer.consume();
inOrder.verify(getStdOutMock())
.println("Consumer [consumer] consume item [" + id + "] produced by [producer]");
}
inOrder.verifyNoMoreInteractions();
}
}

View File

@ -0,0 +1,28 @@
package com.iluwatar.producer.consumer;
import org.junit.Test;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/28/15 - 12:12 AM
*
* @author Jeroen Meulemeester
*/
public class ProducerTest {
@Test(timeout = 6000)
public void testProduce() throws Exception {
final ItemQueue queue = mock(ItemQueue.class);
final Producer producer = new Producer("producer", queue);
producer.produce();
verify(queue).put(any(Item.class));
verifyNoMoreInteractions(queue);
}
}

View File

@ -0,0 +1,53 @@
package com.iluwatar.producer.consumer;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,103 @@
package com.iluwatar.property;
import org.junit.Test;
import static com.iluwatar.property.Character.Type;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Date: 12/28/15 - 7:46 PM
*
* @author Jeroen Meulemeester
*/
public class CharacterTest {
@Test
public void testPrototypeStats() throws Exception {
final Character prototype = new Character();
for (final Stats stat : Stats.values()) {
assertFalse(prototype.has(stat));
assertNull(prototype.get(stat));
final Integer expectedValue = stat.ordinal();
prototype.set(stat, expectedValue);
assertTrue(prototype.has(stat));
assertEquals(expectedValue, prototype.get(stat));
prototype.remove(stat);
assertFalse(prototype.has(stat));
assertNull(prototype.get(stat));
}
}
@Test
public void testCharacterStats() throws Exception {
final Character prototype = new Character();
for (final Stats stat : Stats.values()) {
prototype.set(stat, stat.ordinal());
}
final Character mage = new Character(Type.MAGE, prototype);
for (final Stats stat : Stats.values()) {
final Integer expectedValue = stat.ordinal();
assertTrue(mage.has(stat));
assertEquals(expectedValue, mage.get(stat));
}
}
@Test
public void testToString() throws Exception {
final Character prototype = new Character();
prototype.set(Stats.ARMOR, 1);
prototype.set(Stats.AGILITY, 2);
prototype.set(Stats.INTELLECT, 3);
assertEquals("Stats:\n - AGILITY:2\n - ARMOR:1\n - INTELLECT:3\n", prototype.toString());
final Character stupid = new Character(Type.ROGUE, prototype);
stupid.remove(Stats.INTELLECT);
assertEquals("Character type: ROGUE\nStats:\n - AGILITY:2\n - ARMOR:1\n", stupid.toString());
final Character weak = new Character("weak", prototype);
weak.remove(Stats.ARMOR);
assertEquals("Player: weak\nStats:\n - AGILITY:2\n - INTELLECT:3\n", weak.toString());
}
@Test
public void testName() throws Exception {
final Character prototype = new Character();
prototype.set(Stats.ARMOR, 1);
prototype.set(Stats.INTELLECT, 2);
assertNull(prototype.name());
final Character stupid = new Character(Type.ROGUE, prototype);
stupid.remove(Stats.INTELLECT);
assertNull(stupid.name());
final Character weak = new Character("weak", prototype);
weak.remove(Stats.ARMOR);
assertEquals("weak", weak.name());
}
@Test
public void testType() throws Exception {
final Character prototype = new Character();
prototype.set(Stats.ARMOR, 1);
prototype.set(Stats.INTELLECT, 2);
assertNull(prototype.type());
final Character stupid = new Character(Type.ROGUE, prototype);
stupid.remove(Stats.INTELLECT);
assertEquals(Type.ROGUE, stupid.type());
final Character weak = new Character("weak", prototype);
weak.remove(Stats.ARMOR);
assertNull(weak.type());
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package com.iluwatar.prototype;
import org.junit.Test;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
/**
* Date: 12/28/15 - 8:34 PM
*
* @author Jeroen Meulemeester
*/
public class HeroFactoryImplTest {
@Test
public void testFactory() throws Exception {
final Mage mage = mock(Mage.class);
final Warlord warlord = mock(Warlord.class);
final Beast beast = mock(Beast.class);
when(mage.clone()).thenThrow(CloneNotSupportedException.class);
when(warlord.clone()).thenThrow(CloneNotSupportedException.class);
when(beast.clone()).thenThrow(CloneNotSupportedException.class);
final HeroFactoryImpl factory = new HeroFactoryImpl(mage, warlord, beast);
assertNull(factory.createMage());
assertNull(factory.createWarlord());
assertNull(factory.createBeast());
verify(mage).clone();
verify(warlord).clone();
verify(beast).clone();
verifyNoMoreInteractions(mage, warlord, beast);
}
}

View File

@ -0,0 +1,66 @@
package com.iluwatar.prototype;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
/**
* Date: 12/28/15 - 8:45 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class PrototypeTest<P extends Prototype> {
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[]{new OrcBeast(), "Orcish wolf"},
new Object[]{new OrcMage(), "Orcish mage"},
new Object[]{new OrcWarlord(), "Orcish warlord"},
new Object[]{new ElfBeast(), "Elven eagle"},
new Object[]{new ElfMage(), "Elven mage"},
new Object[]{new ElfWarlord(), "Elven warlord"}
);
}
/**
* The tested prototype instance
*/
private final Prototype testedPrototype;
/**
* The expected {@link Prototype#toString()} value
*/
private final String expectedToString;
/**
* Create a new test instance, using the given test object and expected value
*
* @param testedPrototype The tested prototype instance
* @param expectedToString The expected {@link Prototype#toString()} value
*/
public PrototypeTest(final Prototype testedPrototype, final String expectedToString) {
this.expectedToString = expectedToString;
this.testedPrototype = testedPrototype;
}
@Test
public void testPrototype() throws Exception {
assertEquals(this.expectedToString, this.testedPrototype.toString());
final Object clone = this.testedPrototype.clone();
assertNotNull(clone);
assertNotSame(clone, this.testedPrototype);
assertSame(this.testedPrototype.getClass(), clone.getClass());
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,53 @@
package com.iluwatar.proxy;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,22 @@
package com.iluwatar.proxy;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/28/15 - 9:02 PM
*
* @author Jeroen Meulemeester
*/
public class WizardTest {
@Test
public void testToString() throws Exception {
final String[] wizardNames = {"Gandalf", "Dumbledore", "Oz", "Merlin"};
for (final String name : wizardNames) {
assertEquals(name, new Wizard(name).toString());
}
}
}

View File

@ -0,0 +1,38 @@
package com.iluwatar.proxy;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
/**
* Date: 12/28/15 - 9:18 PM
*
* @author Jeroen Meulemeester
*/
public class WizardTowerProxyTest extends StdOutTest {
@Test
public void testEnter() throws Exception {
final Wizard[] wizards = new Wizard[]{
new Wizard("Gandalf"),
new Wizard("Dumbledore"),
new Wizard("Oz"),
new Wizard("Merlin")
};
final WizardTowerProxy tower = new WizardTowerProxy();
for (final Wizard wizard : wizards) {
tower.enter(wizard);
}
final InOrder inOrder = inOrder(getStdOutMock());
inOrder.verify(getStdOutMock()).println("Gandalf enters the tower.");
inOrder.verify(getStdOutMock()).println("Dumbledore enters the tower.");
inOrder.verify(getStdOutMock()).println("Oz enters the tower.");
inOrder.verify(getStdOutMock()).println("Merlin is not allowed to enter!");
inOrder.verifyNoMoreInteractions();
}
}

View File

@ -0,0 +1,38 @@
package com.iluwatar.proxy;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
/**
* Date: 12/28/15 - 9:18 PM
*
* @author Jeroen Meulemeester
*/
public class WizardTowerTest extends StdOutTest {
@Test
public void testEnter() throws Exception {
final Wizard[] wizards = new Wizard[]{
new Wizard("Gandalf"),
new Wizard("Dumbledore"),
new Wizard("Oz"),
new Wizard("Merlin")
};
final WizardTower tower = new WizardTower();
for (final Wizard wizard : wizards) {
tower.enter(wizard);
}
final InOrder inOrder = inOrder(getStdOutMock());
inOrder.verify(getStdOutMock()).println("Gandalf enters the tower.");
inOrder.verify(getStdOutMock()).println("Dumbledore enters the tower.");
inOrder.verify(getStdOutMock()).println("Oz enters the tower.");
inOrder.verify(getStdOutMock()).println("Merlin enters the tower.");
inOrder.verifyNoMoreInteractions();
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,27 @@
package com.iluwatar.resource.acquisition.is.initialization;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
/**
* Date: 12/28/15 - 9:31 PM
*
* @author Jeroen Meulemeester
*/
public class ClosableTest extends StdOutTest {
@Test
public void testOpenClose() throws Exception {
final InOrder inOrder = inOrder(getStdOutMock());
try (final SlidingDoor door = new SlidingDoor(); final TreasureChest chest = new TreasureChest()) {
inOrder.verify(getStdOutMock()).println("Sliding door opens.");
inOrder.verify(getStdOutMock()).println("Treasure chest opens.");
}
inOrder.verify(getStdOutMock()).println("Treasure chest closes.");
inOrder.verify(getStdOutMock()).println("Sliding door closes.");
inOrder.verifyNoMoreInteractions();
}
}

View File

@ -0,0 +1,53 @@
package com.iluwatar.resource.acquisition.is.initialization;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,82 @@
package com.iluwatar.servant;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Date: 12/28/15 - 9:40 PM
*
* @author Jeroen Meulemeester
*/
public class KingTest {
@Test
public void testHungrySoberUncomplimentedKing() {
final King king = new King();
king.changeMood();
assertFalse(king.getMood());
}
@Test
public void testFedSoberUncomplimentedKing() {
final King king = new King();
king.getFed();
king.changeMood();
assertFalse(king.getMood());
}
@Test
public void testHungryDrunkUncomplimentedKing() {
final King king = new King();
king.getDrink();
king.changeMood();
assertFalse(king.getMood());
}
@Test
public void testHungrySoberComplimentedKing() {
final King king = new King();
king.receiveCompliments();
king.changeMood();
assertFalse(king.getMood());
}
@Test
public void testFedDrunkUncomplimentedKing() {
final King king = new King();
king.getFed();
king.getDrink();
king.changeMood();
assertTrue(king.getMood());
}
@Test
public void testFedSoberComplimentedKing() {
final King king = new King();
king.getFed();
king.receiveCompliments();
king.changeMood();
assertFalse(king.getMood());
}
@Test
public void testFedDrunkComplimentedKing() {
final King king = new King();
king.getFed();
king.getDrink();
king.receiveCompliments();
king.changeMood();
assertFalse(king.getMood());
}
@Test
public void testHungryDrunkComplimentedKing() {
final King king = new King();
king.getDrink();
king.receiveCompliments();
king.changeMood();
assertFalse(king.getMood());
}
}

View File

@ -0,0 +1,46 @@
package com.iluwatar.servant;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Date: 12/28/15 - 9:52 PM
*
* @author Jeroen Meulemeester
*/
public class QueenTest {
@Test
public void testNotFlirtyUncomplemented() throws Exception {
final Queen queen = new Queen();
queen.setFlirtiness(false);
queen.changeMood();
assertFalse(queen.getMood());
}
@Test
public void testNotFlirtyComplemented() throws Exception {
final Queen queen = new Queen();
queen.setFlirtiness(false);
queen.receiveCompliments();
queen.changeMood();
assertFalse(queen.getMood());
}
@Test
public void testFlirtyUncomplemented() throws Exception {
final Queen queen = new Queen();
queen.changeMood();
assertFalse(queen.getMood());
}
@Test
public void testFlirtyComplemented() throws Exception {
final Queen queen = new Queen();
queen.receiveCompliments();
queen.changeMood();
assertTrue(queen.getMood());
}
}

View File

@ -0,0 +1,70 @@
package com.iluwatar.servant;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
/**
* Date: 12/28/15 - 10:02 PM
*
* @author Jeroen Meulemeester
*/
public class ServantTest {
@Test
public void testFeed() throws Exception {
final Royalty royalty = mock(Royalty.class);
final Servant servant = new Servant("test");
servant.feed(royalty);
verify(royalty).getFed();
verifyNoMoreInteractions(royalty);
}
@Test
public void testGiveWine() throws Exception {
final Royalty royalty = mock(Royalty.class);
final Servant servant = new Servant("test");
servant.giveWine(royalty);
verify(royalty).getDrink();
verifyNoMoreInteractions(royalty);
}
@Test
public void testGiveCompliments() throws Exception {
final Royalty royalty = mock(Royalty.class);
final Servant servant = new Servant("test");
servant.giveCompliments(royalty);
verify(royalty).receiveCompliments();
verifyNoMoreInteractions(royalty);
}
@Test
public void testCheckIfYouWillBeHanged() throws Exception {
final Royalty goodMoodRoyalty = mock(Royalty.class);
when(goodMoodRoyalty.getMood()).thenReturn(true);
final Royalty badMoodRoyalty = mock(Royalty.class);
when(badMoodRoyalty.getMood()).thenReturn(true);
final ArrayList<Royalty> goodCompany = new ArrayList<>();
goodCompany.add(goodMoodRoyalty);
goodCompany.add(goodMoodRoyalty);
goodCompany.add(goodMoodRoyalty);
final ArrayList<Royalty> badCompany = new ArrayList<>();
goodCompany.add(goodMoodRoyalty);
goodCompany.add(goodMoodRoyalty);
goodCompany.add(badMoodRoyalty);
assertTrue(new Servant("test").checkIfYouWillBeHanged(goodCompany));
assertTrue(new Servant("test").checkIfYouWillBeHanged(badCompany));
}
}

View File

@ -22,5 +22,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -12,8 +12,37 @@ import javax.persistence.Version;
*/
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class BaseEntity {
public abstract class BaseEntity {
@Version
private Long version;
/**
* Indicates the unique id of this entity
*
* @return The id of the entity, or 'null' when not persisted
*/
public abstract Long getId();
/**
* Set the id of this entity
*
* @param id The new id
*/
public abstract void setId(Long id);
/**
* Get the name of this entity
*
* @return The name of the entity
*/
public abstract String getName();
/**
* Set the name of this entity
*
* @param name The new name
*/
public abstract void setName(final String name);
}

View File

@ -1,41 +1,56 @@
package com.iluwatar.servicelayer.hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.iluwatar.servicelayer.spell.Spell;
import com.iluwatar.servicelayer.spellbook.Spellbook;
import com.iluwatar.servicelayer.wizard.Wizard;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
*
* Produces the Hibernate {@link SessionFactory}.
*
*/
public class HibernateUtil {
private static final SessionFactory SESSION_FACTORY;
static {
try {
SESSION_FACTORY =
new Configuration().addAnnotatedClass(Wizard.class).addAnnotatedClass(Spellbook.class)
.addAnnotatedClass(Spell.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.setProperty("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
.setProperty("hibernate.current_session_context_class", "thread")
.setProperty("hibernate.show_sql", "true")
.setProperty("hibernate.hbm2ddl.auto", "create-drop").buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* The cached session factory
*/
private static volatile SessionFactory sessionFactory;
private HibernateUtil() {
}
public static SessionFactory getSessionFactory() {
return SESSION_FACTORY;
/**
* Create the current session factory instance, create a new one when there is none yet.
*
* @return The session factory
*/
public static synchronized SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
sessionFactory =
new Configuration().addAnnotatedClass(Wizard.class).addAnnotatedClass(Spellbook.class)
.addAnnotatedClass(Spell.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.setProperty("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
.setProperty("hibernate.current_session_context_class", "thread")
.setProperty("hibernate.show_sql", "true")
.setProperty("hibernate.hbm2ddl.auto", "create-drop").buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
return sessionFactory;
}
/**
* Drop the current connection, resulting in a create-drop clean database next time. This is
* mainly used for JUnit testing since one test should not influence the other
*/
public static void dropSession() {
getSessionFactory().close();
sessionFactory = null;
}
}

View File

@ -1,12 +1,12 @@
package com.iluwatar.servicelayer.spell;
import com.iluwatar.servicelayer.common.DaoBaseImpl;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import com.iluwatar.servicelayer.common.DaoBaseImpl;
/**
*
* SpellDao implementation.
@ -24,7 +24,6 @@ public class SpellDaoImpl extends DaoBaseImpl<Spell> implements SpellDao {
Criteria criteria = session.createCriteria(persistentClass);
criteria.add(Restrictions.eq("name", name));
result = (Spell) criteria.uniqueResult();
result.getSpellbook().getWizards().size();
tx.commit();
} catch (Exception e) {
if (tx != null) {

View File

@ -6,6 +6,7 @@ import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@ -50,7 +51,7 @@ public class Spellbook extends BaseEntity {
private String name;
@ManyToMany(mappedBy = "spellbooks")
@ManyToMany(mappedBy = "spellbooks", fetch = FetchType.EAGER)
private Set<Wizard> wizards;
@OneToMany(mappedBy = "spellbook", orphanRemoval = true, cascade = CascadeType.ALL)

View File

@ -1,5 +1,8 @@
package com.iluwatar.servicelayer.app;
import com.iluwatar.servicelayer.hibernate.HibernateUtil;
import org.junit.After;
import org.junit.Test;
/**
@ -14,4 +17,10 @@ public class AppTest {
String[] args = {};
App.main(args);
}
@After
public void tearDown() throws Exception {
HibernateUtil.dropSession();
}
}

View File

@ -0,0 +1,123 @@
package com.iluwatar.servicelayer.common;
import com.iluwatar.servicelayer.hibernate.HibernateUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* Date: 12/28/15 - 10:53 PM
*
* @author Jeroen Meulemeester
*/
public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E>> {
/**
* The number of entities stored before each test
*/
private static final int INITIAL_COUNT = 5;
/**
* The unique id generator, shared between all entities
*/
private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
/**
* Factory, used to create new entity instances with the given name
*/
private final Function<String, E> factory;
/**
* The tested data access object
*/
private final D dao;
/**
* Create a new test using the given factory and dao
*
* @param factory The factory, used to create new entity instances with the given name
* @param dao The tested data access object
*/
public BaseDaoTest(final Function<String, E> factory, final D dao) {
this.factory = factory;
this.dao = dao;
}
@Before
public void setUp() throws Exception {
for (int i = 0; i < INITIAL_COUNT; i++) {
final String className = dao.persistentClass.getSimpleName();
final String entityName = String.format("%s%d", className, ID_GENERATOR.incrementAndGet());
this.dao.persist(this.factory.apply(entityName));
}
}
@After
public void tearDown() throws Exception {
HibernateUtil.dropSession();
}
protected final D getDao() {
return this.dao;
}
@Test
public void testFind() throws Exception {
final List<E> all = this.dao.findAll();
for (final E entity : all) {
final E byId = this.dao.find(entity.getId());
assertNotNull(byId);
assertEquals(byId.getId(), byId.getId());
}
}
@Test
public void testDelete() throws Exception {
final List<E> originalEntities = this.dao.findAll();
this.dao.delete(originalEntities.get(1));
this.dao.delete(originalEntities.get(2));
final List<E> entitiesLeft = this.dao.findAll();
assertNotNull(entitiesLeft);
assertEquals(INITIAL_COUNT - 2, entitiesLeft.size());
}
@Test
public void testFindAll() throws Exception {
final List<E> all = this.dao.findAll();
assertNotNull(all);
assertEquals(INITIAL_COUNT, all.size());
}
@Test
public void testSetId() throws Exception {
final E entity = this.factory.apply("name");
assertNull(entity.getId());
final Long expectedId = Long.valueOf(1);
entity.setId(expectedId);
assertEquals(expectedId, entity.getId());
}
@Test
public void testSetName() throws Exception {
final E entity = this.factory.apply("name");
assertEquals("name", entity.getName());
assertEquals("name", entity.toString());
final String expectedName = "new name";
entity.setName(expectedName);
assertEquals(expectedName, entity.getName());
assertEquals(expectedName, entity.toString());
}
}

View File

@ -0,0 +1,138 @@
package com.iluwatar.servicelayer.magic;
import com.iluwatar.servicelayer.spell.Spell;
import com.iluwatar.servicelayer.spell.SpellDao;
import com.iluwatar.servicelayer.spellbook.Spellbook;
import com.iluwatar.servicelayer.spellbook.SpellbookDao;
import com.iluwatar.servicelayer.wizard.Wizard;
import com.iluwatar.servicelayer.wizard.WizardDao;
import org.junit.Test;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
/**
* Date: 12/29/15 - 12:06 AM
*
* @author Jeroen Meulemeester
*/
public class MagicServiceImplTest {
@Test
public void testFindAllWizards() throws Exception {
final WizardDao wizardDao = mock(WizardDao.class);
final SpellbookDao spellbookDao = mock(SpellbookDao.class);
final SpellDao spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao);
service.findAllWizards();
verify(wizardDao).findAll();
verifyNoMoreInteractions(wizardDao, spellbookDao, spellDao);
}
@Test
public void testFindAllSpellbooks() throws Exception {
final WizardDao wizardDao = mock(WizardDao.class);
final SpellbookDao spellbookDao = mock(SpellbookDao.class);
final SpellDao spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao);
service.findAllSpellbooks();
verify(spellbookDao).findAll();
verifyNoMoreInteractions(wizardDao, spellbookDao, spellDao);
}
@Test
public void testFindAllSpells() throws Exception {
final WizardDao wizardDao = mock(WizardDao.class);
final SpellbookDao spellbookDao = mock(SpellbookDao.class);
final SpellDao spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao);
service.findAllSpells();
verify(spellDao).findAll();
verifyNoMoreInteractions(wizardDao, spellbookDao, spellDao);
}
@Test
public void testFindWizardsWithSpellbook() throws Exception {
final String bookname = "bookname";
final Spellbook spellbook = mock(Spellbook.class);
final Set<Wizard> wizards = new HashSet<>();
wizards.add(mock(Wizard.class));
wizards.add(mock(Wizard.class));
wizards.add(mock(Wizard.class));
when(spellbook.getWizards()).thenReturn(wizards);
final SpellbookDao spellbookDao = mock(SpellbookDao.class);
when(spellbookDao.findByName(eq(bookname))).thenReturn(spellbook);
final WizardDao wizardDao = mock(WizardDao.class);
final SpellDao spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao, spellbook);
final List<Wizard> result = service.findWizardsWithSpellbook(bookname);
verify(spellbookDao).findByName(eq(bookname));
verify(spellbook).getWizards();
assertNotNull(result);
assertEquals(3, result.size());
verifyNoMoreInteractions(wizardDao, spellbookDao, spellDao);
}
@Test
public void testFindWizardsWithSpell() throws Exception {
final Set<Wizard> wizards = new HashSet<>();
wizards.add(mock(Wizard.class));
wizards.add(mock(Wizard.class));
wizards.add(mock(Wizard.class));
final Spellbook spellbook = mock(Spellbook.class);
when(spellbook.getWizards()).thenReturn(wizards);
final SpellbookDao spellbookDao = mock(SpellbookDao.class);
final WizardDao wizardDao = mock(WizardDao.class);
final Spell spell = mock(Spell.class);
when(spell.getSpellbook()).thenReturn(spellbook);
final String spellName = "spellname";
final SpellDao spellDao = mock(SpellDao.class);
when(spellDao.findByName(eq(spellName))).thenReturn(spell);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao, spellbook);
final List<Wizard> result = service.findWizardsWithSpell(spellName);
verify(spellDao).findByName(eq(spellName));
verify(spellbook).getWizards();
assertNotNull(result);
assertEquals(3, result.size());
verifyNoMoreInteractions(wizardDao, spellbookDao, spellDao);
}
}

View File

@ -0,0 +1,35 @@
package com.iluwatar.servicelayer.spell;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Date: 12/28/15 - 11:02 PM
*
* @author Jeroen Meulemeester
*/
public class SpellDaoImplTest extends BaseDaoTest<Spell, SpellDaoImpl> {
public SpellDaoImplTest() {
super(Spell::new, new SpellDaoImpl());
}
@Test
public void testFindByName() throws Exception {
final SpellDaoImpl dao = getDao();
final List<Spell> allSpells = dao.findAll();
for (final Spell spell : allSpells) {
final Spell spellByName = dao.findByName(spell.getName());
assertNotNull(spellByName);
assertEquals(spell.getId(), spellByName.getId());
assertEquals(spell.getName(), spellByName.getName());
}
}
}

View File

@ -0,0 +1,35 @@
package com.iluwatar.servicelayer.spellbook;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Date: 12/28/15 - 11:44 PM
*
* @author Jeroen Meulemeester
*/
public class SpellbookDaoImplTest extends BaseDaoTest<Spellbook, SpellbookDaoImpl> {
public SpellbookDaoImplTest() {
super(Spellbook::new, new SpellbookDaoImpl());
}
@Test
public void testFindByName() throws Exception {
final SpellbookDaoImpl dao = getDao();
final List<Spellbook> allBooks = dao.findAll();
for (final Spellbook book : allBooks) {
final Spellbook spellByName = dao.findByName(book.getName());
assertNotNull(spellByName);
assertEquals(book.getId(), spellByName.getId());
assertEquals(book.getName(), spellByName.getName());
}
}
}

View File

@ -0,0 +1,35 @@
package com.iluwatar.servicelayer.wizard;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Date: 12/28/15 - 11:46 PM
*
* @author Jeroen Meulemeester
*/
public class WizardDaoImplTest extends BaseDaoTest<Wizard, WizardDaoImpl> {
public WizardDaoImplTest() {
super(Wizard::new, new WizardDaoImpl());
}
@Test
public void testFindByName() throws Exception {
final WizardDaoImpl dao = getDao();
final List<Wizard> allWizards = dao.findAll();
for (final Wizard spell : allWizards) {
final Wizard byName = dao.findByName(spell.getName());
assertNotNull(byName);
assertEquals(spell.getId(), byName.getId());
assertEquals(spell.getName(), byName.getName());
}
}
}

View File

@ -32,7 +32,9 @@ public class ServiceLocator {
*/
InitContext ctx = new InitContext();
serviceObj = (Service) ctx.lookup(serviceJndiName);
serviceCache.addService(serviceObj);
if (serviceObj != null) { // Only cache a service if it actually exists
serviceCache.addService(serviceObj);
}
return serviceObj;
}
}

View File

@ -0,0 +1,46 @@
package com.iluwatar.servicelocator;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* Date: 12/29/15 - 19:07 PM
*
* @author Jeroen Meulemeester
*/
public class ServiceLocatorTest {
/**
* Verify if we just receive 'null' when requesting a non-existing service
*/
@Test
public void testGetNonExistentService() {
assertNull(ServiceLocator.getService("fantastic/unicorn/service"));
assertNull(ServiceLocator.getService("another/fantastic/unicorn/service"));
}
/**
* Verify if we get the same cached instance when requesting the same service twice
*/
@Test
public void testServiceCache() {
final String[] serviceNames = new String[]{
"jndi/serviceA", "jndi/serviceB"
};
for (final String serviceName : serviceNames) {
final Service service = ServiceLocator.getService(serviceName);
assertNotNull(service);
assertEquals(serviceName, service.getName());
assertTrue(service.getId() > 0); // The id is generated randomly, but the minimum value is '1'
assertSame(service, ServiceLocator.getService(serviceName));
}
}
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.singleton;
/**
* Date: 12/29/15 - 19:20 PM
*
* @author Jeroen Meulemeester
*/
public class EnumIvoryTowerTest extends SingletonTest<EnumIvoryTower> {
/**
* Create a new singleton test instance using the given 'getInstance' method
*/
public EnumIvoryTowerTest() {
super(() -> EnumIvoryTower.INSTANCE);
}
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.singleton;
/**
* Date: 12/29/15 - 19:22 PM
*
* @author Jeroen Meulemeester
*/
public class InitializingOnDemandHolderIdiomTest extends SingletonTest<InitializingOnDemandHolderIdiom> {
/**
* Create a new singleton test instance using the given 'getInstance' method
*/
public InitializingOnDemandHolderIdiomTest() {
super(InitializingOnDemandHolderIdiom::getInstance);
}
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.singleton;
/**
* Date: 12/29/15 - 19:23 PM
*
* @author Jeroen Meulemeester
*/
public class IvoryTowerTest extends SingletonTest<IvoryTower> {
/**
* Create a new singleton test instance using the given 'getInstance' method
*/
public IvoryTowerTest() {
super(IvoryTower::getInstance);
}
}

View File

@ -1,90 +0,0 @@
package com.iluwatar.singleton;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.Test;
/**
* This class provides several test case that test singleton construction.
*
* The first proves that multiple calls to the singleton getInstance object are the same when called
* in the SAME thread. The second proves that multiple calls to the singleton getInstance object are
* the same when called in the DIFFERENT thread.
*
*/
public class LazyLoadedSingletonThreadSafetyTest {
private static final int NUM_THREADS = 5;
private List<ThreadSafeLazyLoadedIvoryTower> threadObjects = Collections
.synchronizedList(new ArrayList<>());
// NullObject class so Callable has to return something
private class NullObject {
private NullObject() {}
}
@Test
public void testMultipleCallsReturnTheSameObjectInSameThread() {
// Create several instances in the same calling thread
ThreadSafeLazyLoadedIvoryTower instance1 = ThreadSafeLazyLoadedIvoryTower.getInstance();
ThreadSafeLazyLoadedIvoryTower instance2 = ThreadSafeLazyLoadedIvoryTower.getInstance();
ThreadSafeLazyLoadedIvoryTower instance3 = ThreadSafeLazyLoadedIvoryTower.getInstance();
// now check they are equal
assertEquals(instance1, instance1);
assertEquals(instance1, instance2);
assertEquals(instance2, instance3);
assertEquals(instance1, instance3);
}
@Test
public void testMultipleCallsReturnTheSameObjectInDifferentThreads()
throws InterruptedException, ExecutionException {
{
// create several threads and inside each callable instantiate the singleton class
ExecutorService executorService = Executors.newSingleThreadExecutor();
List<Callable<NullObject>> threadList = new ArrayList<>();
for (int i = 0; i < NUM_THREADS; i++) {
threadList.add(new SingletonCreatingThread());
}
ExecutorService service = Executors.newCachedThreadPool();
List<Future<NullObject>> results = service.invokeAll(threadList);
// wait for all of the threads to complete
for (Future res : results) {
res.get();
}
// tidy up the executor
executorService.shutdown();
}
{
// now check the contents that were added to threadObjects by each thread
assertEquals(NUM_THREADS, threadObjects.size());
assertEquals(threadObjects.get(0), threadObjects.get(1));
assertEquals(threadObjects.get(1), threadObjects.get(2));
assertEquals(threadObjects.get(2), threadObjects.get(3));
assertEquals(threadObjects.get(3), threadObjects.get(4));
}
}
private class SingletonCreatingThread implements Callable<NullObject> {
@Override
public NullObject call() {
// instantiate the thread safety class and add to list to test afterwards
ThreadSafeLazyLoadedIvoryTower instance = ThreadSafeLazyLoadedIvoryTower.getInstance();
threadObjects.add(instance);
return new NullObject();// return null object (cannot return Void)
}
}
}

View File

@ -0,0 +1,88 @@
package com.iluwatar.singleton;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Supplier;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
/**
* This class provides several test case that test singleton construction.
*
* The first proves that multiple calls to the singleton getInstance object are the same when called
* in the SAME thread. The second proves that multiple calls to the singleton getInstance object are
* the same when called in the DIFFERENT thread.
*
* Date: 12/29/15 - 19:25 PM
*
* @author Jeroen Meulemeester
* @author Richard Jones
*/
public abstract class SingletonTest<S> {
/**
* The singleton's getInstance method
*/
private final Supplier<S> singletonInstanceMethod;
/**
* Create a new singleton test instance using the given 'getInstance' method
*
* @param singletonInstanceMethod The singleton's getInstance method
*/
public SingletonTest(final Supplier<S> singletonInstanceMethod) {
this.singletonInstanceMethod = singletonInstanceMethod;
}
/**
* Test the singleton in a non-concurrent setting
*/
@Test
public void testMultipleCallsReturnTheSameObjectInSameThread() {
// Create several instances in the same calling thread
S instance1 = this.singletonInstanceMethod.get();
S instance2 = this.singletonInstanceMethod.get();
S instance3 = this.singletonInstanceMethod.get();
// now check they are equal
assertSame(instance1, instance2);
assertSame(instance1, instance3);
assertSame(instance2, instance3);
}
/**
* Test singleton instance in a concurrent setting
*/
@Test(timeout = 10000)
public void testMultipleCallsReturnTheSameObjectInDifferentThreads() throws Exception {
// Create 10000 tasks and inside each callable instantiate the singleton class
final List<Callable<S>> tasks = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
tasks.add(this.singletonInstanceMethod::get);
}
// Use up to 8 concurrent threads to handle the tasks
final ExecutorService executorService = Executors.newFixedThreadPool(8);
final List<Future<S>> results = executorService.invokeAll(tasks);
// wait for all of the threads to complete
final S expectedInstance = this.singletonInstanceMethod.get();
for (Future<S> res : results) {
final S instance = res.get();
assertNotNull(instance);
assertSame(expectedInstance, instance);
}
// tidy up the executor
executorService.shutdown();
}
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.singleton;
/**
* Date: 12/29/15 - 19:26 PM
*
* @author Jeroen Meulemeester
*/
public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDoubleCheckLocking> {
/**
* Create a new singleton test instance using the given 'getInstance' method
*/
public ThreadSafeDoubleCheckLockingTest() {
super(ThreadSafeDoubleCheckLocking::getInstance);
}
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.singleton;
/**
* Date: 12/29/15 - 19:26 PM
*
* @author Jeroen Meulemeester
*/
public class ThreadSafeLazyLoadedIvoryTowerTest extends SingletonTest<ThreadSafeLazyLoadedIvoryTower> {
/**
* Create a new singleton test instance using the given 'getInstance' method
*/
public ThreadSafeLazyLoadedIvoryTowerTest() {
super(ThreadSafeLazyLoadedIvoryTower::getInstance);
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,111 @@
package com.iluwatar.specification.creature;
import com.iluwatar.specification.property.Color;
import com.iluwatar.specification.property.Movement;
import com.iluwatar.specification.property.Size;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Date: 12/29/15 - 7:47 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class CreatureTest {
/**
* @return The tested {@link Creature} instance and its expected specs
*/
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[]{new Dragon(), "Dragon", Size.LARGE, Movement.FLYING, Color.RED},
new Object[]{new Goblin(), "Goblin", Size.SMALL, Movement.WALKING, Color.GREEN},
new Object[]{new KillerBee(), "KillerBee", Size.SMALL, Movement.FLYING, Color.LIGHT},
new Object[]{new Octopus(), "Octopus", Size.NORMAL, Movement.SWIMMING, Color.DARK},
new Object[]{new Shark(), "Shark", Size.NORMAL, Movement.SWIMMING, Color.LIGHT},
new Object[]{new Troll(), "Troll", Size.LARGE, Movement.WALKING, Color.DARK}
);
}
/**
* The tested creature
*/
private final Creature testedCreature;
/**
* The expected name of the tested creature
*/
private final String name;
/**
* The expected size of the tested creature
*/
private final Size size;
/**
* The expected movement type of the tested creature
*/
private final Movement movement;
/**
* The expected color of the tested creature
*/
private final Color color;
/**
* @param testedCreature The tested creature
* @param name The expected name of the creature
* @param size The expected size of the creature
* @param movement The expected movement type of the creature
* @param color The expected color of the creature
*/
public CreatureTest(final Creature testedCreature, final String name, final Size size,
final Movement movement, final Color color) {
this.testedCreature = testedCreature;
this.name = name;
this.size = size;
this.movement = movement;
this.color = color;
}
@Test
public void testGetName() throws Exception {
assertEquals(this.name, this.testedCreature.getName());
}
@Test
public void testGetSize() throws Exception {
assertEquals(this.size, this.testedCreature.getSize());
}
@Test
public void testGetMovement() throws Exception {
assertEquals(this.movement, this.testedCreature.getMovement());
}
@Test
public void testGetColor() throws Exception {
assertEquals(this.color, this.testedCreature.getColor());
}
@Test
public void testToString() throws Exception {
final String toString = this.testedCreature.toString();
assertNotNull(toString);
assertEquals(
String.format("%s [size=%s, movement=%s, color=%s]", name, size, movement, color),
toString
);
}
}

View File

@ -0,0 +1,37 @@
package com.iluwatar.specification.selector;
import com.iluwatar.specification.creature.Creature;
import com.iluwatar.specification.property.Color;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Date: 12/29/15 - 7:35 PM
*
* @author Jeroen Meulemeester
*/
public class ColorSelectorTest {
/**
* Verify if the color selector gives the correct results
*/
@Test
public void testColor() {
final Creature greenCreature = mock(Creature.class);
when(greenCreature.getColor()).thenReturn(Color.GREEN);
final Creature redCreature = mock(Creature.class);
when(redCreature.getColor()).thenReturn(Color.RED);
final ColorSelector greenSelector = new ColorSelector(Color.GREEN);
assertTrue(greenSelector.test(greenCreature));
assertFalse(greenSelector.test(redCreature));
}
}

View File

@ -0,0 +1,38 @@
package com.iluwatar.specification.selector;
import com.iluwatar.specification.creature.Creature;
import com.iluwatar.specification.property.Color;
import com.iluwatar.specification.property.Movement;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Date: 12/29/15 - 7:37 PM
*
* @author Jeroen Meulemeester
*/
public class MovementSelectorTest {
/**
* Verify if the movement selector gives the correct results
*/
@Test
public void testMovement() {
final Creature swimmingCreature = mock(Creature.class);
when(swimmingCreature.getMovement()).thenReturn(Movement.SWIMMING);
final Creature flyingCreature = mock(Creature.class);
when(flyingCreature.getMovement()).thenReturn(Movement.FLYING);
final MovementSelector swimmingSelector = new MovementSelector(Movement.SWIMMING);
assertTrue(swimmingSelector.test(swimmingCreature));
assertFalse(swimmingSelector.test(flyingCreature));
}
}

View File

@ -0,0 +1,36 @@
package com.iluwatar.specification.selector;
import com.iluwatar.specification.creature.Creature;
import com.iluwatar.specification.property.Size;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Date: 12/29/15 - 7:43 PM
*
* @author Jeroen Meulemeester
*/
public class SizeSelectorTest {
/**
* Verify if the size selector gives the correct results
*/
@Test
public void testMovement() {
final Creature normalCreature = mock(Creature.class);
when(normalCreature.getSize()).thenReturn(Size.NORMAL);
final Creature smallCreature = mock(Creature.class);
when(smallCreature.getSize()).thenReturn(Size.SMALL);
final SizeSelector normalSelector = new SizeSelector(Size.NORMAL);
assertTrue(normalSelector.test(normalCreature));
assertFalse(normalSelector.test(smallCreature));
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -3,7 +3,7 @@ package com.iluwatar.state;
import org.junit.Test;
/**
*
*
* Application test
*
*/

View File

@ -0,0 +1,90 @@
package com.iluwatar.state;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;
import java.io.PrintStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
/**
* Date: 12/29/15 - 8:27 PM
*
* @author Jeroen Meulemeester
*/
public class MammothTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Switch to a complete mammoth 'mood'-cycle and verify if the observed mood matches the expected
* value.
*/
@Test
public void testTimePasses() {
final InOrder inOrder = Mockito.inOrder(this.stdOutMock);
final Mammoth mammoth = new Mammoth();
mammoth.observe();
inOrder.verify(this.stdOutMock).println("The mammoth is calm and peaceful.");
inOrder.verifyNoMoreInteractions();
mammoth.timePasses();
inOrder.verify(this.stdOutMock).println("The mammoth gets angry!");
inOrder.verifyNoMoreInteractions();
mammoth.observe();
inOrder.verify(this.stdOutMock).println("The mammoth is furious!");
inOrder.verifyNoMoreInteractions();
mammoth.timePasses();
inOrder.verify(this.stdOutMock).println("The mammoth calms down.");
inOrder.verifyNoMoreInteractions();
mammoth.observe();
inOrder.verify(this.stdOutMock).println("The mammoth is calm and peaceful.");
inOrder.verifyNoMoreInteractions();
}
/**
* Verify if {@link Mammoth#toString()} gives the expected value
*/
@Test
public void testToString() {
final String toString = new Mammoth().toString();
assertNotNull(toString);
assertEquals("The mammoth", toString);
}
}

View File

@ -0,0 +1,155 @@
package com.iluwatar.stepbuilder;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Date: 12/29/15 - 9:21 PM
*
* @author Jeroen Meulemeester
*/
public class CharacterStepBuilderTest {
/**
* Build a new wizard {@link Character} and verify if it has the expected attributes
*/
@Test
public void testBuildWizard() {
final Character character = CharacterStepBuilder.newBuilder()
.name("Merlin")
.wizardClass("alchemist")
.withSpell("poison")
.withAbility("invisibility")
.withAbility("wisdom")
.noMoreAbilities()
.build();
assertEquals("Merlin", character.getName());
assertEquals("alchemist", character.getWizardClass());
assertEquals("poison", character.getSpell());
assertNotNull(character.toString());
final List<String> abilities = character.getAbilities();
assertNotNull(abilities);
assertEquals(2, abilities.size());
assertTrue(abilities.contains("invisibility"));
assertTrue(abilities.contains("wisdom"));
}
/**
* Build a new wizard {@link Character} without spell or abilities and verify if it has the
* expected attributes
*/
@Test
public void testBuildPoorWizard() {
final Character character = CharacterStepBuilder.newBuilder()
.name("Merlin")
.wizardClass("alchemist")
.noSpell()
.build();
assertEquals("Merlin", character.getName());
assertEquals("alchemist", character.getWizardClass());
assertNull(character.getSpell());
assertNull(character.getAbilities());
assertNotNull(character.toString());
}
/**
* Build a new wizard {@link Character} and verify if it has the expected attributes
*/
@Test
public void testBuildWeakWizard() {
final Character character = CharacterStepBuilder.newBuilder()
.name("Merlin")
.wizardClass("alchemist")
.withSpell("poison")
.noAbilities()
.build();
assertEquals("Merlin", character.getName());
assertEquals("alchemist", character.getWizardClass());
assertEquals("poison", character.getSpell());
assertNull(character.getAbilities());
assertNotNull(character.toString());
}
/**
* Build a new warrior {@link Character} and verify if it has the expected attributes
*/
@Test
public void testBuildWarrior() {
final Character character = CharacterStepBuilder.newBuilder()
.name("Cuauhtemoc")
.fighterClass("aztec")
.withWeapon("spear")
.withAbility("speed")
.withAbility("strength")
.noMoreAbilities()
.build();
assertEquals("Cuauhtemoc", character.getName());
assertEquals("aztec", character.getFighterClass());
assertEquals("spear", character.getWeapon());
assertNotNull(character.toString());
final List<String> abilities = character.getAbilities();
assertNotNull(abilities);
assertEquals(2, abilities.size());
assertTrue(abilities.contains("speed"));
assertTrue(abilities.contains("strength"));
}
/**
* Build a new wizard {@link Character} without weapon and abilities and verify if it has the
* expected attributes
*/
@Test
public void testBuildPoorWarrior() {
final Character character = CharacterStepBuilder.newBuilder()
.name("Poor warrior")
.fighterClass("none")
.noWeapon()
.build();
assertEquals("Poor warrior", character.getName());
assertEquals("none", character.getFighterClass());
assertNull(character.getWeapon());
assertNull(character.getAbilities());
assertNotNull(character.toString());
}
/**
* Build a new warrior {@link Character} without any abilities, but with a weapon and verify if it
* has the expected attributes
*/
@Test
public void testBuildWeakWarrior() {
final Character character = CharacterStepBuilder.newBuilder()
.name("Weak warrior")
.fighterClass("none")
.withWeapon("Slingshot")
.noAbilities()
.build();
assertEquals("Weak warrior", character.getName());
assertEquals("none", character.getFighterClass());
assertEquals("Slingshot", character.getWeapon());
assertNull(character.getAbilities());
assertNotNull(character.toString());
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,48 @@
package com.iluwatar.strategy;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/29/15 - 10:50 PM
*
* @author Jeroen Meulemeester
*/
public class DragonSlayerTest {
/**
* Verify if the dragon slayer uses the strategy during battle
*/
@Test
public void testGoToBattle() {
final DragonSlayingStrategy strategy = mock(DragonSlayingStrategy.class);
final DragonSlayer dragonSlayer = new DragonSlayer(strategy);
dragonSlayer.goToBattle();
verify(strategy).execute();
verifyNoMoreInteractions(strategy);
}
/**
* Verify if the dragon slayer uses the new strategy during battle after a change of strategy
*/
@Test
public void testChangeStrategy() throws Exception {
final DragonSlayingStrategy initialStrategy = mock(DragonSlayingStrategy.class);
final DragonSlayer dragonSlayer = new DragonSlayer(initialStrategy);
dragonSlayer.goToBattle();
verify(initialStrategy).execute();
final DragonSlayingStrategy newStrategy = mock(DragonSlayingStrategy.class);
dragonSlayer.changeStrategy(newStrategy);
dragonSlayer.goToBattle();
verify(newStrategy).execute();
verifyNoMoreInteractions(initialStrategy, newStrategy);
}
}

View File

@ -0,0 +1,104 @@
package com.iluwatar.strategy;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collection;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/29/15 - 10:58 PM
*
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class DragonSlayingStrategyTest {
/**
* @return The test parameters for each cycle
*/
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[]{
new MeleeStrategy(),
"With your Excalibur you severe the dragon's head!"
},
new Object[]{
new ProjectileStrategy(),
"You shoot the dragon with the magical crossbow and it falls dead on the ground!"
},
new Object[]{
new SpellStrategy(),
"You cast the spell of disintegration and the dragon vaporizes in a pile of dust!"
}
);
}
/**
* The tested strategy
*/
private final DragonSlayingStrategy strategy;
/**
* The expected action on the std-out
*/
private final String expectedResult;
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Create a new test instance for the given strategy
*
* @param strategy The tested strategy
* @param expectedResult The expected result
*/
public DragonSlayingStrategyTest(final DragonSlayingStrategy strategy, final String expectedResult) {
this.strategy = strategy;
this.expectedResult = expectedResult;
}
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Test if executing the strategy gives the correct response
*/
@Test
public void testExecute() {
this.strategy.execute();
verify(this.stdOutMock).println(this.expectedResult);
verifyNoMoreInteractions(this.stdOutMock);
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
package com.iluwatar.templatemethod;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/29/15 - 18:15 PM
*
* @author Jeroen Meulemeester
*/
public class HalflingThiefTest {
/**
* Verify if the thief uses the provided stealing method
*/
@Test
public void testSteal() {
final StealingMethod method = mock(StealingMethod.class);
final HalflingThief thief = new HalflingThief(method);
thief.steal();
verify(method).steal();
verifyNoMoreInteractions(method);
}
/**
* Verify if the thief uses the provided stealing method, and the new method after changing it
*/
@Test
public void testChangeMethod() {
final StealingMethod initialMethod = mock(StealingMethod.class);
final HalflingThief thief = new HalflingThief(initialMethod);
thief.steal();
verify(initialMethod).steal();
final StealingMethod newMethod = mock(StealingMethod.class);
thief.changeMethod(newMethod);
thief.steal();
verify(newMethod).steal();
verifyNoMoreInteractions(initialMethod, newMethod);
}
}

View File

@ -0,0 +1,23 @@
package com.iluwatar.templatemethod;
/**
* Date: 12/30/15 - 18:12 PM
*
* @author Jeroen Meulemeester
*/
public class HitAndRunMethodTest extends StealingMethodTest<HitAndRunMethod> {
/**
* Create a new test for the {@link HitAndRunMethod}
*/
public HitAndRunMethodTest() {
super(
new HitAndRunMethod(),
"old goblin woman",
"The target has been chosen as old goblin woman.",
"Approach the old goblin woman from behind.",
"Grab the handbag and run away fast!"
);
}
}

View File

@ -0,0 +1,142 @@
package com.iluwatar.templatemethod;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
import java.io.PrintStream;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/30/15 - 18:12 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StealingMethodTest<M extends StealingMethod> {
/**
* The tested stealing method
*/
private final M method;
/**
* The expected target
*/
private final String expectedTarget;
/**
* The expected target picking result
*/
private final String expectedTargetResult;
/**
* The expected confusion method
*/
private final String expectedConfuseMethod;
/**
* The expected stealing method
*/
private final String expectedStealMethod;
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Create a new test for the given stealing method, together with the expected results
*
* @param method The tested stealing method
* @param expectedTarget The expected target name
* @param expectedTargetResult The expected target picking result
* @param expectedConfuseMethod The expected confusion method
* @param expectedStealMethod The expected stealing method
*/
public StealingMethodTest(final M method, String expectedTarget, final String expectedTargetResult,
final String expectedConfuseMethod, final String expectedStealMethod) {
this.method = method;
this.expectedTarget = expectedTarget;
this.expectedTargetResult = expectedTargetResult;
this.expectedConfuseMethod = expectedConfuseMethod;
this.expectedStealMethod = expectedStealMethod;
}
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Verify if the thief picks the correct target
*/
@Test
public void testPickTarget() {
assertEquals(expectedTarget, this.method.pickTarget());
}
/**
* Verify if the target confusing step goes as planned
*/
@Test
public void testConfuseTarget() {
verifyZeroInteractions(this.stdOutMock);
this.method.confuseTarget(this.expectedTarget);
verify(this.stdOutMock).println(this.expectedConfuseMethod);
verifyNoMoreInteractions(this.stdOutMock);
}
/**
* Verify if the stealing step goes as planned
*/
@Test
public void testStealTheItem() {
verifyZeroInteractions(this.stdOutMock);
this.method.stealTheItem(this.expectedTarget);
verify(this.stdOutMock).println(this.expectedStealMethod);
verifyNoMoreInteractions(this.stdOutMock);
}
/**
* Verify if the complete steal process goes as planned
*/
@Test
public void testSteal() {
final InOrder inOrder = inOrder(this.stdOutMock);
this.method.steal();
inOrder.verify(this.stdOutMock).println(this.expectedTargetResult);
inOrder.verify(this.stdOutMock).println(this.expectedConfuseMethod);
inOrder.verify(this.stdOutMock).println(this.expectedStealMethod);
inOrder.verifyNoMoreInteractions();
}
}

View File

@ -0,0 +1,23 @@
package com.iluwatar.templatemethod;
/**
* Date: 12/30/15 - 18:19 PM
*
* @author Jeroen Meulemeester
*/
public class SubtleMethodTest extends StealingMethodTest<SubtleMethod> {
/**
* Create a new test for the {@link SubtleMethod}
*/
public SubtleMethodTest() {
super(
new SubtleMethod(),
"shop keeper",
"The target has been chosen as shop keeper.",
"Approach the shop keeper with tears running and hug him!",
"While in close contact grab the shop keeper's wallet."
);
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -7,7 +7,7 @@ package com.iluwatar.threadpool;
*/
public class CoffeeMakingTask extends Task {
private static final int TIME_PER_CUP = 300;
private static final int TIME_PER_CUP = 100;
public CoffeeMakingTask(int numCups) {
super(numCups * TIME_PER_CUP);

View File

@ -7,7 +7,7 @@ package com.iluwatar.threadpool;
*/
public class PotatoPeelingTask extends Task {
private static final int TIME_PER_POTATO = 500;
private static final int TIME_PER_POTATO = 200;
public PotatoPeelingTask(int numPotatoes) {
super(numPotatoes * TIME_PER_POTATO);

View File

@ -1,19 +1,21 @@
package com.iluwatar.threadpool;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
*
* Abstract base class for tasks
*
*/
public abstract class Task {
private static int nextId = 1;
private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
private final int id;
private final int timeMs;
public Task(final int timeMs) {
this.id = nextId++;
this.id = ID_GENERATOR.incrementAndGet();
this.timeMs = timeMs;
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.threadpool;
/**
* Date: 12/30/15 - 18:23 PM
*
* @author Jeroen Meulemeester
*/
public class CoffeeMakingTaskTest extends TaskTest<CoffeeMakingTask> {
/**
* Create a new test instance
*/
public CoffeeMakingTaskTest() {
super(CoffeeMakingTask::new, 100);
}
}

View File

@ -0,0 +1,17 @@
package com.iluwatar.threadpool;
/**
* Date: 12/30/15 - 18:23 PM
*
* @author Jeroen Meulemeester
*/
public class PotatoPeelingTaskTest extends TaskTest<PotatoPeelingTask> {
/**
* Create a new test instance
*/
public PotatoPeelingTaskTest() {
super(PotatoPeelingTask::new, 200);
}
}

View File

@ -0,0 +1,121 @@
package com.iluwatar.threadpool;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Date: 12/30/15 - 18:22 PM
*
* @author Jeroen Meulemeester
*/
public abstract class TaskTest<T extends Task> {
/**
* The number of tasks used during the concurrency test
*/
private static final int TASK_COUNT = 128 * 1024;
/**
* The number of threads used during the concurrency test
*/
private static final int THREAD_COUNT = 8;
/**
* The task factory, used to create new test items
*/
private final Function<Integer, T> factory;
/**
* The expected time needed to run the task 1 single time, in milli seconds
*/
private final int expectedExecutionTime;
/**
* Create a new test instance
*
* @param factory The task factory, used to create new test items
* @param expectedExecutionTime The expected time needed to run the task 1 time, in milli seconds
*/
public TaskTest(final Function<Integer, T> factory, final int expectedExecutionTime) {
this.factory = factory;
this.expectedExecutionTime = expectedExecutionTime;
}
/**
* Verify if the generated id is unique for each task, even if the tasks are created in separate
* threads
*/
@Test(timeout = 10000)
public void testIdGeneration() throws Exception {
final ExecutorService service = Executors.newFixedThreadPool(THREAD_COUNT);
final List<Callable<Integer>> tasks = new ArrayList<>();
for (int i = 0; i < TASK_COUNT; i++) {
tasks.add(() -> factory.apply(1).getId());
}
final List<Integer> ids = service.invokeAll(tasks)
.stream()
.map(TaskTest::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
service.shutdownNow();
final long uniqueIdCount = ids.stream()
.distinct()
.count();
assertEquals(TASK_COUNT, ids.size());
assertEquals(TASK_COUNT, uniqueIdCount);
}
/**
* Verify if the time per execution of a task matches the actual time required to execute the task
* a given number of times
*/
@Test
public void testTimeMs() {
for (int i = 0; i < 10; i++) {
assertEquals(this.expectedExecutionTime * i, this.factory.apply(i).getTimeMs());
}
}
/**
* Verify if the task has some sort of {@link T#toString()}, different from 'null'
*/
@Test
public void testToString() {
assertNotNull(this.factory.apply(0).toString());
}
/**
* Extract the result from a future or returns 'null' when an exception occurred
*
* @param future The future we want the result from
* @param <O> The result type
* @return The result or 'null' when a checked exception occurred
*/
private static <O> O get(Future<O> future) {
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
return null;
}
}
}

View File

@ -0,0 +1,31 @@
package com.iluwatar.threadpool;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/30/15 - 18:21 PM
*
* @author Jeroen Meulemeester
*/
public class WorkerTest {
/**
* Verify if a worker does the actual job
*/
@Test
public void testRun() {
final Task task = mock(Task.class);
final Worker worker = new Worker(task);
verifyZeroInteractions(task);
worker.run();
verify(task).getTimeMs();
verifyNoMoreInteractions(task);
}
}

View File

@ -0,0 +1,68 @@
package com.iluwatar.tolerantreader;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
/**
* Date: 12/30/15 - 18:39 PM
*
* @author Jeroen Meulemeester
*/
public class RainbowFishSerializerTest {
/**
* Create a temporary folder, used to generate files in during this test
*/
@Rule
public final TemporaryFolder testFolder = new TemporaryFolder();
/**
* Rainbow fish version 1 used during the tests
*/
private static final RainbowFish V1 = new RainbowFish("version1", 1, 2, 3);
/**
* Rainbow fish version 2 used during the tests
*/
private static final RainbowFishV2 V2 = new RainbowFishV2("version2", 4, 5, 6, true, false, true);
/**
* Verify if a fish, written as version 1 can be read back as version 1
*/
@Test
public void testWriteV1ReadV1() throws Exception {
final File outputFile = this.testFolder.newFile();
RainbowFishSerializer.writeV1(V1, outputFile.getPath());
final RainbowFish fish = RainbowFishSerializer.readV1(outputFile.getPath());
assertNotSame(V1, fish);
assertEquals(V1.getName(), fish.getName());
assertEquals(V1.getAge(), fish.getAge());
assertEquals(V1.getLengthMeters(), fish.getLengthMeters());
assertEquals(V1.getWeightTons(), fish.getWeightTons());
}
/**
* Verify if a fish, written as version 2 can be read back as version 1
*/
@Test
public void testWriteV2ReadV1() throws Exception {
final File outputFile = this.testFolder.newFile();
RainbowFishSerializer.writeV2(V2, outputFile.getPath());
final RainbowFish fish = RainbowFishSerializer.readV1(outputFile.getPath());
assertNotSame(V2, fish);
assertEquals(V2.getName(), fish.getName());
assertEquals(V2.getAge(), fish.getAge());
assertEquals(V2.getLengthMeters(), fish.getLengthMeters());
assertEquals(V2.getWeightTons(), fish.getWeightTons());
}
}

View File

@ -0,0 +1,26 @@
package com.iluwatar.tolerantreader;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/30/15 - 18:34 PM
*
* @author Jeroen Meulemeester
*/
public class RainbowFishTest {
/**
* Verify if the getters of a {@link RainbowFish} return the expected values
*/
@Test
public void testValues() {
final RainbowFish fish = new RainbowFish("name", 1, 2, 3);
assertEquals("name", fish.getName());
assertEquals(1, fish.getAge());
assertEquals(2, fish.getLengthMeters());
assertEquals(3, fish.getWeightTons());
}
}

View File

@ -0,0 +1,29 @@
package com.iluwatar.tolerantreader;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/30/15 - 18:35 PM
*
* @author Jeroen Meulemeester
*/
public class RainbowFishV2Test {
/**
* Verify if the getters of a {@link RainbowFish} return the expected values
*/
@Test
public void testValues() {
final RainbowFishV2 fish = new RainbowFishV2("name", 1, 2, 3, false, true, false);
assertEquals("name", fish.getName());
assertEquals(1, fish.getAge());
assertEquals(2, fish.getLengthMeters());
assertEquals(3, fish.getWeightTons());
assertEquals(false, fish.getSleeping());
assertEquals(true, fish.getHungry());
assertEquals(false, fish.getAngry());
}
}

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -41,6 +41,6 @@ public class App {
}
private static void waiting() throws Exception {
Thread.sleep(2500);
Thread.sleep(750);
}
}

View File

@ -25,15 +25,14 @@ public class BallThread extends Thread {
public void run() {
while (isRunning) {
while (!isSuspended) {
if (!isSuspended) {
twin.draw();
twin.move();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
try {
Thread.sleep(250);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,62 @@
package com.iluwatar.twin;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/30/15 - 18:44 PM
*
* @author Jeroen Meulemeester
*/
public class BallItemTest extends StdOutTest {
@Test
public void testClick() {
final BallThread ballThread = mock(BallThread.class);
final BallItem ballItem = new BallItem();
ballItem.setTwin(ballThread);
final InOrder inOrder = inOrder(ballThread);
for (int i = 0; i < 10; i++) {
ballItem.click();
inOrder.verify(ballThread).suspendMe();
ballItem.click();
inOrder.verify(ballThread).resumeMe();
}
inOrder.verifyNoMoreInteractions();
}
@Test
public void testDoDraw() {
final BallItem ballItem = new BallItem();
final BallThread ballThread = mock(BallThread.class);
ballItem.setTwin(ballThread);
ballItem.draw();
verify(getStdOutMock()).println("draw");
verify(getStdOutMock()).println("doDraw");
verifyNoMoreInteractions(ballThread, getStdOutMock());
}
@Test
public void testMove() {
final BallItem ballItem = new BallItem();
final BallThread ballThread = mock(BallThread.class);
ballItem.setTwin(ballThread);
ballItem.move();
verify(getStdOutMock()).println("move");
verifyNoMoreInteractions(ballThread, getStdOutMock());
}
}

View File

@ -0,0 +1,89 @@
package com.iluwatar.twin;
import org.junit.Test;
import static java.lang.Thread.UncaughtExceptionHandler;
import static java.lang.Thread.sleep;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Date: 12/30/15 - 18:55 PM
*
* @author Jeroen Meulemeester
*/
public class BallThreadTest {
/**
* Verify if the {@link BallThread} can be resumed
*/
@Test(timeout = 5000)
public void testSuspend() throws Exception {
final BallThread ballThread = new BallThread();
final BallItem ballItem = mock(BallItem.class);
ballThread.setTwin(ballItem);
ballThread.start();
verify(ballItem, timeout(2000).atLeastOnce()).draw();
verify(ballItem, timeout(2000).atLeastOnce()).move();
ballThread.suspendMe();
sleep(1000);
ballThread.stopMe();
ballThread.join();
verifyNoMoreInteractions(ballItem);
}
/**
* Verify if the {@link BallThread} can be resumed
*/
@Test(timeout = 5000)
public void testResume() throws Exception {
final BallThread ballThread = new BallThread();
final BallItem ballItem = mock(BallItem.class);
ballThread.setTwin(ballItem);
ballThread.suspendMe();
ballThread.start();
sleep(1000);
verifyZeroInteractions(ballItem);
ballThread.resumeMe();
verify(ballItem, timeout(2000).atLeastOnce()).draw();
verify(ballItem, timeout(2000).atLeastOnce()).move();
ballThread.stopMe();
ballThread.join();
verifyNoMoreInteractions(ballItem);
}
/**
* Verify if the {@link BallThread} is interruptible
*/
@Test(timeout = 5000)
public void testInterrupt() throws Exception {
final BallThread ballThread = new BallThread();
final UncaughtExceptionHandler exceptionHandler = mock(UncaughtExceptionHandler.class);
ballThread.setUncaughtExceptionHandler(exceptionHandler);
ballThread.setTwin(mock(BallItem.class));
ballThread.start();
ballThread.interrupt();
ballThread.join();
verify(exceptionHandler).uncaughtException(eq(ballThread), any(RuntimeException.class));
verifyNoMoreInteractions(exceptionHandler);
}
}

Some files were not shown because too many files have changed in this diff Show More