diff --git a/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java b/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java
new file mode 100644
index 0000000..17ad11b
--- /dev/null
+++ b/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.cordmcast.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.event.DefaultEventSinkRegistry;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventSink;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.mcast.api.McastRoute;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.config.basics.McastConfig;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+
+import com.google.common.collect.ImmutableMap;
+import org.opencord.cordmcast.CordMcastStatisticsEvent;
+import org.opencord.cordmcast.CordMcastStatisticsEventListener;
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class McastTestBase {
+
+     // Map to store the forwardingObjective in flowObjectiveService.forward()
+     Map<DeviceId, ForwardingObjective> forwardMap = new HashMap<>();
+     // Map to store the nextObjective in flowObjectiveService.next()
+     Map<DeviceId, NextObjective> nextMap = new HashMap<>();
+     // Device configuration
+     protected static final DeviceId DEVICE_ID_OF_A = DeviceId.deviceId("of:00000a0a0a0a0a00");
+     // Port number
+     protected static final PortNumber PORT_A = PortNumber.portNumber(1048576);
+     protected static final PortNumber PORT_B = PortNumber.portNumber(16);
+     protected static final PortNumber PORT_C = PortNumber.portNumber(24);
+
+     // Connect Point for creating source and sink
+     protected static final ConnectPoint CONNECT_POINT_A = new ConnectPoint(DEVICE_ID_OF_A, PORT_A);
+     protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_A, PORT_B);
+     protected static final ConnectPoint CONNECT_POINT_C = new ConnectPoint(DEVICE_ID_OF_A, PORT_C);
+
+     // serial number of the device A
+     protected static final String SERIAL_NUMBER_OF_DEVICE_A = "serialNumberOfDevA";
+     // Management ip address of the device A
+     protected static final Ip4Address MANAGEMENT_IP_OF_A = Ip4Address.valueOf("10.177.125.4");
+     //Host id configuration
+     protected static final HostId HOST_ID_NONE = HostId.NONE;
+     // Source connect point
+     protected static final  Set<ConnectPoint> SOURCES_CP = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_A));
+     Map<HostId, Set<ConnectPoint>> sources = ImmutableMap.of(HOST_ID_NONE, SOURCES_CP);
+
+     protected static final IpAddress MULTICAST_IP = IpAddress.valueOf("224.0.0.22");
+     protected static final IpAddress SOURCE_IP = IpAddress.valueOf("192.168.1.1");
+     // Creating dummy route with IGMP type.
+     McastRoute route1 = new McastRoute(SOURCE_IP, MULTICAST_IP, McastRoute.Type.IGMP);
+
+     // Creating empty sink used in prevRoute
+     Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList());
+     Map<HostId, Set<ConnectPoint>> sinks = ImmutableMap.of(HOST_ID_NONE, sinksCp);
+
+     // Creating empty source
+     Set<ConnectPoint> sourceCp = new HashSet<ConnectPoint>(Arrays.asList());
+     Map<HostId, Set<ConnectPoint>> emptySource = ImmutableMap.of(HOST_ID_NONE, sourceCp);
+
+     // Flag to check unknown olt device
+     boolean knownOltFlag = false;
+
+     // For the tests reduce events period to 1s
+     protected static final int EVENT_GENERATION_PERIOD = 1;
+
+     class MockCoreService extends CoreServiceAdapter {
+          @Override
+          public ApplicationId registerApplication(String name) {
+               ApplicationId testApplicationId = TestApplicationId.create("org.opencord.cordmcast");
+               return testApplicationId;
+          }
+     }
+
+     class MockFlowObjectiveService extends FlowObjectiveServiceAdapter {
+          @Override
+          public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+              synchronized (forwardMap) {
+                forwardMap.put(deviceId, forwardingObjective);
+                forwardMap.notify();
+              }
+          }
+
+          @Override
+          public void next(DeviceId deviceId, NextObjective nextObjective) {
+             nextMap.put(deviceId, nextObjective);
+          }
+     }
+
+     class TestMastershipService extends MastershipServiceAdapter {
+          @Override
+          public boolean isLocalMaster(DeviceId deviceId) {
+               return true;
+          }
+     }
+
+    protected class MockSadisService implements SadisService {
+
+        @Override
+        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
+            return new MockSubService();
+        }
+
+        @Override
+        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
+            return null;
+        }
+    }
+
+    /**
+     * Mocks the McastConfig class to return vlan id value.
+     */
+    static class MockMcastConfig extends McastConfig {
+        @Override
+        public VlanId egressVlan() {
+            return VlanId.vlanId("4000");
+        }
+    }
+
+    /**
+     * Mocks the network config registry.
+     */
+    @SuppressWarnings("unchecked")
+    static final class TestNetworkConfigRegistry
+            extends NetworkConfigRegistryAdapter {
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            McastConfig mcastConfig = new MockMcastConfig();
+            return (C) mcastConfig;
+        }
+    }
+
+    public static class TestEventDispatcher extends DefaultEventSinkRegistry
+            implements EventDeliveryService {
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public synchronized void post(Event event) {
+            EventSink sink = getSink(event.getClass());
+            checkState(sink != null, "No sink for event %s", event);
+            sink.process(event);
+        }
+
+        @Override
+        public void setDispatchTimeLimit(long millis) {
+
+        }
+
+        @Override
+        public long getDispatchTimeLimit() {
+            return 0;
+        }
+    }
+
+    public static class MockCordMcastStatisticsEventListener implements CordMcastStatisticsEventListener {
+        protected List<CordMcastStatisticsEvent> mcastEventList = new ArrayList<CordMcastStatisticsEvent>();
+
+        @Override
+        public void event(CordMcastStatisticsEvent event) {
+            mcastEventList.add(event);
+        }
+    }
+
+    private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
+        MockSubscriberAndDeviceInformation deviceA =
+                new MockSubscriberAndDeviceInformation(SERIAL_NUMBER_OF_DEVICE_A, MANAGEMENT_IP_OF_A);
+
+        @Override
+        public SubscriberAndDeviceInformation get(String id) {
+            return SERIAL_NUMBER_OF_DEVICE_A.equals(id) ? deviceA : null;
+        }
+
+        @Override
+        public void invalidateAll() {
+        }
+
+        @Override
+        public void invalidateId(String id) {
+        }
+
+        @Override
+        public SubscriberAndDeviceInformation getfromCache(String id) {
+            return null;
+        }
+    }
+
+    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
+
+        MockSubscriberAndDeviceInformation(String id, Ip4Address ipAddress) {
+            this.setId(id);
+            this.setIPAddress(ipAddress);
+            this.setUplinkPort((int) PORT_A.toLong());
+        }
+    }
+
+    class MockDeviceService extends DeviceServiceAdapter {
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            if (DEVICE_ID_OF_A.equals(deviceId)) {
+                DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
+                        .set(AnnotationKeys.MANAGEMENT_ADDRESS, MANAGEMENT_IP_OF_A.toString());
+                SparseAnnotations annotations = annotationsBuilder.build();
+                Annotations[] da = {annotations};
+
+                Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_A, Device.Type.OTHER, "", "",
+                        "", SERIAL_NUMBER_OF_DEVICE_A, null, da);
+                return deviceA;
+            } else {
+                knownOltFlag = true;
+            }
+            return null;
+        }
+    }
+
+     public OutputInstruction outputPort(TrafficTreatment trafficTreatment) {
+         List<Instruction> listOfInstructions = trafficTreatment.allInstructions();
+         OutputInstruction output = null;
+         for (Instruction intruction : listOfInstructions) {
+           output = (OutputInstruction) intruction;
+         }
+         return output;
+     }
+
+     public IPCriterion ipAddress(TrafficSelector trafficSelector) {
+       Set<Criterion> criterionSet = trafficSelector.criteria();
+       Iterator<Criterion> it = criterionSet.iterator();
+       IPCriterion ipCriterion = null;
+       while (it.hasNext()) {
+           Criterion criteria = it.next();
+           if (Criterion.Type.IPV4_DST == criteria.type()) {
+             ipCriterion = (IPCriterion) criteria;
+           }
+       }
+       return (IPCriterion) ipCriterion;
+     }
+
+}
