diff --git a/flux/pom.xml b/flux/pom.xml
index 3b06d299c..7b0afd626 100644
--- a/flux/pom.xml
+++ b/flux/pom.xml
@@ -14,5 +14,10 @@
junit
test
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/flux/src/test/java/com/iluwatar/flux/action/ContentTest.java b/flux/src/test/java/com/iluwatar/flux/action/ContentTest.java
new file mode 100644
index 000000000..7781c1d90
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/action/ContentTest.java
@@ -0,0 +1,24 @@
+package com.iluwatar.flux.action;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Date: 12/12/15 - 10:11 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class ContentTest {
+
+ @Test
+ public void testToString() throws Exception {
+ for (final Content content : Content.values()) {
+ final String toString = content.toString();
+ assertNotNull(toString);
+ assertFalse(toString.trim().isEmpty());
+ }
+ }
+
+}
diff --git a/flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java b/flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java
new file mode 100644
index 000000000..02fa781e6
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java
@@ -0,0 +1,24 @@
+package com.iluwatar.flux.action;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Date: 12/12/15 - 10:15 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class MenuItemTest {
+
+ @Test
+ public void testToString() throws Exception {
+ for (final MenuItem menuItem : MenuItem.values()) {
+ final String toString = menuItem.toString();
+ assertNotNull(toString);
+ assertFalse(toString.trim().isEmpty());
+ }
+ }
+
+}
diff --git a/flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java b/flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java
new file mode 100644
index 000000000..8e1977dd8
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java
@@ -0,0 +1,92 @@
+package com.iluwatar.flux.dispatcher;
+
+import com.iluwatar.flux.action.Action;
+import com.iluwatar.flux.action.ActionType;
+import com.iluwatar.flux.action.Content;
+import com.iluwatar.flux.action.ContentAction;
+import com.iluwatar.flux.action.MenuAction;
+import com.iluwatar.flux.action.MenuItem;
+import com.iluwatar.flux.store.Store;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+/**
+ * Date: 12/12/15 - 8:22 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class DispatcherTest {
+
+ /**
+ * Dispatcher is a singleton with no way to reset it's internal state back to the beginning.
+ * Replace the instance with a fresh one before each test to make sure test cases have no
+ * influence on each other.
+ */
+ @Before
+ public void setUp() throws Exception {
+ final Constructor constructor;
+ constructor = Dispatcher.class.getDeclaredConstructor();
+ constructor.setAccessible(true);
+
+ final Field field = Dispatcher.class.getDeclaredField("instance");
+ field.setAccessible(true);
+ field.set(Dispatcher.getInstance(), constructor.newInstance());
+ }
+
+ @Test
+ public void testGetInstance() throws Exception {
+ assertNotNull(Dispatcher.getInstance());
+ assertSame(Dispatcher.getInstance(), Dispatcher.getInstance());
+ }
+
+ @Test
+ public void testMenuItemSelected() throws Exception {
+ final Dispatcher dispatcher = Dispatcher.getInstance();
+
+ final Store store = mock(Store.class);
+ dispatcher.registerStore(store);
+ dispatcher.menuItemSelected(MenuItem.HOME);
+ dispatcher.menuItemSelected(MenuItem.COMPANY);
+
+ // We expect 4 events, 2 menu selections and 2 content change actions
+ final ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(Action.class);
+ verify(store, times(4)).onAction(actionCaptor.capture());
+ verifyNoMoreInteractions(store);
+
+ final List actions = actionCaptor.getAllValues();
+ final List menuActions = actions.stream()
+ .filter(a -> a.getType().equals(ActionType.MENU_ITEM_SELECTED))
+ .map(a -> (MenuAction) a)
+ .collect(Collectors.toList());
+
+ final List contentActions = actions.stream()
+ .filter(a -> a.getType().equals(ActionType.CONTENT_CHANGED))
+ .map(a -> (ContentAction) a)
+ .collect(Collectors.toList());
+
+ assertEquals(2, menuActions.size());
+ assertEquals(1, menuActions.stream().map(MenuAction::getMenuItem).filter(MenuItem.HOME::equals).count());
+ assertEquals(1, menuActions.stream().map(MenuAction::getMenuItem).filter(MenuItem.COMPANY::equals).count());
+
+ assertEquals(2, contentActions.size());
+ assertEquals(1, contentActions.stream().map(ContentAction::getContent).filter(Content.PRODUCTS::equals).count());
+ assertEquals(1, contentActions.stream().map(ContentAction::getContent).filter(Content.COMPANY::equals).count());
+
+ }
+
+}
diff --git a/flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java b/flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java
new file mode 100644
index 000000000..7c9ce0a69
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java
@@ -0,0 +1,47 @@
+package com.iluwatar.flux.store;
+
+import com.iluwatar.flux.action.Content;
+import com.iluwatar.flux.action.ContentAction;
+import com.iluwatar.flux.action.MenuAction;
+import com.iluwatar.flux.action.MenuItem;
+import com.iluwatar.flux.view.View;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+/**
+ * Date: 12/12/15 - 10:18 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class ContentStoreTest {
+
+ @Test
+ public void testOnAction() throws Exception {
+ final ContentStore contentStore = new ContentStore();
+
+ final View view = mock(View.class);
+ contentStore.registerView(view);
+
+ verifyZeroInteractions(view);
+
+ // Content should not react on menu action ...
+ contentStore.onAction(new MenuAction(MenuItem.PRODUCTS));
+ verifyZeroInteractions(view);
+
+ // ... but it should react on a content action
+ contentStore.onAction(new ContentAction(Content.COMPANY));
+ verify(view, times(1)).storeChanged(eq(contentStore));
+ verifyNoMoreInteractions(view);
+ assertEquals(Content.COMPANY, contentStore.getContent());
+
+ }
+
+}
diff --git a/flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java b/flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java
new file mode 100644
index 000000000..2e7f80590
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java
@@ -0,0 +1,47 @@
+package com.iluwatar.flux.store;
+
+import com.iluwatar.flux.action.Content;
+import com.iluwatar.flux.action.ContentAction;
+import com.iluwatar.flux.action.MenuAction;
+import com.iluwatar.flux.action.MenuItem;
+import com.iluwatar.flux.view.View;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+/**
+ * Date: 12/12/15 - 10:18 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class MenuStoreTest {
+
+ @Test
+ public void testOnAction() throws Exception {
+ final MenuStore menuStore = new MenuStore();
+
+ final View view = mock(View.class);
+ menuStore.registerView(view);
+
+ verifyZeroInteractions(view);
+
+ // Menu should not react on content action ...
+ menuStore.onAction(new ContentAction(Content.COMPANY));
+ verifyZeroInteractions(view);
+
+ // ... but it should react on a menu action
+ menuStore.onAction(new MenuAction(MenuItem.PRODUCTS));
+ verify(view, times(1)).storeChanged(eq(menuStore));
+ verifyNoMoreInteractions(view);
+ assertEquals(MenuItem.PRODUCTS, menuStore.getSelected());
+
+ }
+
+}
diff --git a/flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java b/flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java
new file mode 100644
index 000000000..49cecd24a
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java
@@ -0,0 +1,33 @@
+package com.iluwatar.flux.view;
+
+import com.iluwatar.flux.action.Content;
+import com.iluwatar.flux.store.ContentStore;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ * Date: 12/12/15 - 10:31 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class ContentViewTest {
+
+ @Test
+ public void testStoreChanged() throws Exception {
+ final ContentStore store = mock(ContentStore.class);
+ when(store.getContent()).thenReturn(Content.PRODUCTS);
+
+ final ContentView view = new ContentView();
+ view.storeChanged(store);
+
+ verify(store, times(1)).getContent();
+ verifyNoMoreInteractions(store);
+ }
+
+}
diff --git a/flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java b/flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java
new file mode 100644
index 000000000..2534515b0
--- /dev/null
+++ b/flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java
@@ -0,0 +1,50 @@
+package com.iluwatar.flux.view;
+
+import com.iluwatar.flux.action.Action;
+import com.iluwatar.flux.action.MenuItem;
+import com.iluwatar.flux.dispatcher.Dispatcher;
+import com.iluwatar.flux.store.MenuStore;
+import com.iluwatar.flux.store.Store;
+
+import org.junit.Test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ * Date: 12/12/15 - 10:31 PM
+ *
+ * @author Jeroen Meulemeester
+ */
+public class MenuViewTest {
+
+ @Test
+ public void testStoreChanged() throws Exception {
+ final MenuStore store = mock(MenuStore.class);
+ when(store.getSelected()).thenReturn(MenuItem.HOME);
+
+ final MenuView view = new MenuView();
+ view.storeChanged(store);
+
+ verify(store, times(1)).getSelected();
+ verifyNoMoreInteractions(store);
+ }
+
+ @Test
+ public void testItemClicked() throws Exception {
+ final Store store = mock(Store.class);
+ Dispatcher.getInstance().registerStore(store);
+
+ final MenuView view = new MenuView();
+ view.itemClicked(MenuItem.PRODUCTS);
+
+ // We should receive a menu click action and a content changed action
+ verify(store, times(2)).onAction(any(Action.class));
+
+ }
+
+}