diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
index 2e95c6c..d57613b 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
@@ -59,7 +59,7 @@
     public static final String EVENT_CHANNEL_NAME = "onos.topology";
     private EventHandler eventHandler = new EventHandler();
 
-    private final TopologyDatastore datastore;
+    private TopologyDatastore datastore;
     private final TopologyImpl topology = new TopologyImpl();
     private final IControllerRegistryService registryService;
     private CopyOnWriteArrayList<ITopologyListener> topologyListeners;
@@ -1241,4 +1241,14 @@
 
         return collection;
     }
+    /**
+     * Replaces the internal datastore instance.
+     *
+     * @param dataStore instance
+     *
+     * @exclude Backdoor for unit testing purpose only, do not use.
+     */
+    void debugReplaceDataStore(final TopologyDatastore dataStoreService) {
+        this.datastore = dataStoreService;
+    }
 }
diff --git a/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
new file mode 100644
index 0000000..934ce7d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
@@ -0,0 +1,324 @@
+package net.onrc.onos.core.topology;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.datagrid.IDatagridService;
+import net.onrc.onos.core.datagrid.IEventChannel;
+import net.onrc.onos.core.datagrid.IEventChannelListener;
+import net.onrc.onos.core.registry.IControllerRegistryService;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
+import net.onrc.onos.core.util.SwitchPort;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for the TopologyManager class in the Topology module.
+ * These test cases only check the sanity of functions in the TopologyManager.
+ * Note that we do not test the eventHandler functions in the TopologyManager class.
+ * DatagridService, DataStoreService, eventChannel, and controllerRegistryService are mocked out.
+ */
+public class TopologyManagerTest {
+    private TopologyManager theTopologyManager;
+    private final String eventChannelName = "onos.topology";
+    private IEventChannel<byte[], TopologyEvent> eventChannel;
+    private IDatagridService datagridService;
+    private TopologyDatastore dataStoreService;
+    private IControllerRegistryService registryService;
+    private CopyOnWriteArrayList<ITopologyListener> topologyListeners;
+    private Collection<TopologyEvent> allTopologyEvents;
+
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws Exception {
+        // Mock objects for testing
+        datagridService = EasyMock.createNiceMock(IDatagridService.class);
+        dataStoreService = EasyMock.createNiceMock(TopologyDatastore.class);
+        registryService = createMock(IControllerRegistryService.class);
+        eventChannel = EasyMock.createNiceMock(IEventChannel.class);
+
+        expect(datagridService.createChannel(
+                eq(eventChannelName),
+                eq(byte[].class),
+                eq(TopologyEvent.class)))
+                .andReturn(eventChannel).once();
+
+        expect(datagridService.addListener(
+                eq(eventChannelName),
+                anyObject(IEventChannelListener.class),
+                eq(byte[].class),
+                eq(TopologyEvent.class)))
+                .andReturn(eventChannel).once();
+
+        expect(dataStoreService.addSwitch(
+                anyObject(SwitchEvent.class),
+                anyObject(Collection.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.deactivateSwitch(
+                anyObject(SwitchEvent.class),
+                anyObject(Collection.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.addPort(
+                anyObject(PortEvent.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.deactivatePort(
+                anyObject(PortEvent.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.addDevice(
+                anyObject(DeviceEvent.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.removeDevice(
+                anyObject(DeviceEvent.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.addLink(
+                anyObject(LinkEvent.class)))
+                .andReturn(true).anyTimes();
+
+        expect(dataStoreService.removeLink(
+                anyObject(LinkEvent.class)))
+                .andReturn(true).anyTimes();
+
+        replay(datagridService);
+        replay(registryService);
+        replay(dataStoreService);
+
+        allTopologyEvents = new CopyOnWriteArrayList<>();
+        expect(eventChannel.getAllEntries()).andReturn(allTopologyEvents);
+        EasyMock.expectLastCall().anyTimes();
+
+        // Create a topologyManager object for testing
+        topologyListeners = new CopyOnWriteArrayList<>();
+        theTopologyManager = new TopologyManager(registryService, topologyListeners);
+        theTopologyManager.startup(datagridService);
+        theTopologyManager.debugReplaceDataStore(dataStoreService);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+
+    }
+
+    /**
+     * Test the Switch discovered and Port discovered functions.
+     */
+    @Test
+    public void testPutSwitchAndPortDiscoveryEvent() {
+        // Mock the eventChannel functions first
+        eventChannel.addEntry(anyObject(byte[].class),
+                anyObject(TopologyEvent.class));
+        EasyMock.expectLastCall().times(3, 3); // (1 switch + 1 port), 1 port
+        replay(eventChannel);
+
+        // mockSwitch has one port
+        Dpid swDPId = new Dpid(100L);
+        PortNumber portId = new PortNumber((short) 1);
+
+        // Generate a new switch event along with a port event
+        SwitchEvent switchEvent = new SwitchEvent(swDPId);
+
+        Collection<PortEvent> portEvents = new ArrayList<PortEvent>();
+        portEvents.add(new PortEvent(swDPId, portId));
+
+        // Call the topologyManager function for adding a switch
+        theTopologyManager.putSwitchDiscoveryEvent(switchEvent, portEvents);
+
+        for (PortEvent portEvent : portEvents) {
+            // Call the topologyManager function for adding a port
+            theTopologyManager.putPortDiscoveryEvent(portEvent);
+        }
+
+        // Verify the function calls
+        verify(eventChannel);
+
+    }
+
+    /**
+     * Test the switch and port removed functions.
+     */
+    @Test
+    public void testRemoveSwitchAndPortDiscoveryEvent() {
+        // Mock the eventChannel functions first
+        eventChannel.removeEntry(anyObject(byte[].class));
+        EasyMock.expectLastCall().times(2, 2); //1 switch, 1 port
+        replay(eventChannel);
+
+        Dpid swDPId = new Dpid(100L);
+        PortNumber portId = new PortNumber((short) 1);
+
+        // Generate a port event
+        Collection<PortEvent> portEvents = new ArrayList<PortEvent>();
+        portEvents.add(new PortEvent(swDPId, portId));
+
+        // Call the topologyManager function for removing a port
+        for (PortEvent portEvent : portEvents) {
+            theTopologyManager.removePortDiscoveryEvent(portEvent);
+        }
+
+        // Call the topologyManager function for removing a switch
+        SwitchEvent switchEvent = new SwitchEvent(swDPId);
+        theTopologyManager.removeSwitchDiscoveryEvent(switchEvent);
+
+        // Verify the function calls
+        verify(eventChannel);
+
+    }
+
+    /**
+     * Test the device discovered function.
+     */
+    @Test
+    public void testPutDeviceDiscoveryEvent() {
+        // Mock the eventChannel functions first
+        eventChannel.addEntry(anyObject(byte[].class),
+                anyObject(TopologyEvent.class));
+        EasyMock.expectLastCall().times(1, 1); // 1 device
+        replay(eventChannel);
+
+        long swDPId = 100L;
+        long portId = 1L;
+
+        // Generate a new device event
+        MACAddress devMac = MACAddress.valueOf("00:AA:11:BB:33:CC");
+        SwitchPort sp = new SwitchPort(swDPId, portId);
+        List<SwitchPort> spLists = new ArrayList<SwitchPort>();
+        spLists.add(sp);
+        DeviceEvent deviceEvent = new DeviceEvent(devMac);
+        deviceEvent.setAttachmentPoints(spLists);
+
+        // Call the topologyManager function for adding a device
+        theTopologyManager.putDeviceDiscoveryEvent(deviceEvent);
+
+        // Verify the function calls
+        verify(eventChannel);
+    }
+
+    /**
+     * Test the device removed function.
+     */
+    @Test
+    public void testRemoveDeviceDiscoveryEvent() {
+        // Mock the eventChannel functions first
+        eventChannel.removeEntry(anyObject(byte[].class));
+        EasyMock.expectLastCall().times(1, 1); // 1 device
+        replay(eventChannel);
+
+        long swDPId = 100L;
+        long portId = 1L;
+
+        // Generate a new device event
+        MACAddress devMac = MACAddress.valueOf("00:AA:11:BB:33:CC");
+        SwitchPort sp = new SwitchPort(swDPId, portId);
+        List<SwitchPort> spLists = new ArrayList<SwitchPort>();
+        spLists.add(sp);
+        DeviceEvent deviceEvent = new DeviceEvent(devMac);
+        deviceEvent.setAttachmentPoints(spLists);
+
+        // Call the topologyManager function for removing a device
+        theTopologyManager.removeDeviceDiscoveryEvent(deviceEvent);
+
+        // Verify the function calls
+        verify(eventChannel);
+    }
+
+    /**
+     * Test the link discovered function.
+     */
+    @Test
+    public void testPutLinkDiscoveryEvent() {
+        // Mock the eventChannel functions first
+        eventChannel.addEntry(anyObject(byte[].class),
+                anyObject(TopologyEvent.class));
+        EasyMock.expectLastCall().times(5, 5); // (2 switch + 2 port + 1 link)
+        replay(eventChannel);
+
+        // Assign the switch and port IDs
+        Dpid sw1DPId = new Dpid(100L);
+        PortNumber port1Id = new PortNumber((short) 1);
+        Dpid sw2DPId = new Dpid(200L);
+        PortNumber port2Id = new PortNumber((short) 2);
+
+        // Generate the switch and port events
+        SwitchEvent switchEvent1 = new SwitchEvent(sw1DPId);
+        Collection<PortEvent> portEvents1 = new ArrayList<PortEvent>();
+        portEvents1.add(new PortEvent(sw1DPId, port1Id));
+
+        // Call the topologyManager function for adding a switch
+        theTopologyManager.putSwitchDiscoveryEvent(switchEvent1, portEvents1);
+
+        // Generate the switch and port events
+        SwitchEvent switchEvent2 = new SwitchEvent(sw2DPId);
+        Collection<PortEvent> portEvents2 = new ArrayList<PortEvent>();
+        portEvents2.add(new PortEvent(sw2DPId, port2Id));
+
+        // Call the topologyManager function for adding a switch
+        theTopologyManager.putSwitchDiscoveryEvent(switchEvent2, portEvents2);
+
+        // Create the link
+        LinkEvent linkEvent = new LinkEvent(sw1DPId, port1Id, sw2DPId, port2Id);
+        theTopologyManager.putLinkDiscoveryEvent(linkEvent);
+
+        // Verify the function calls
+        verify(eventChannel);
+    }
+
+    /**
+     * Test the link removed function.
+     */
+    @Test
+    public void testRemoveLinkDiscoveryEvent() {
+        // Mock the eventChannel functions first
+        eventChannel.removeEntry(anyObject(byte[].class));
+        EasyMock.expectLastCall().times(1, 1); // (1 link)
+        replay(eventChannel);
+
+        // Assign the switch and port IDs
+        Dpid sw1DPId = new Dpid(100L);
+        PortNumber port1Id = new PortNumber((short) 1);
+        Dpid sw2DPId = new Dpid(200L);
+        PortNumber port2Id = new PortNumber((short) 2);
+
+        // Generate the switch and port events
+        SwitchEvent switchEvent1 = new SwitchEvent(sw1DPId);
+        Collection<PortEvent> portEvents1 = new ArrayList<PortEvent>();
+        portEvents1.add(new PortEvent(sw1DPId, port1Id));
+
+        // Call the topologyManager function for adding a switch
+        theTopologyManager.putSwitchDiscoveryEvent(switchEvent1, portEvents1);
+
+        // Generate the switch and port events
+        SwitchEvent switchEvent2 = new SwitchEvent(sw2DPId);
+        Collection<PortEvent> portEvents2 = new ArrayList<PortEvent>();
+        portEvents2.add(new PortEvent(sw2DPId, port2Id));
+
+        // Call the topologyManager function for adding a switch
+        theTopologyManager.putSwitchDiscoveryEvent(switchEvent2, portEvents2);
+
+        // Remove the link
+        LinkEvent linkEventRemove = new LinkEvent(sw1DPId, port1Id, sw2DPId, port2Id);
+        theTopologyManager.removeLinkDiscoveryEvent(linkEventRemove);
+
+        // Verify the function calls
+        verify(eventChannel);
+    }
+
+}
