diff --git a/app/src/test/java/org/opencord/maclearner/app/impl/MacLearnerManagerTest.java b/app/src/test/java/org/opencord/maclearner/app/impl/MacLearnerManagerTest.java
new file mode 100644
index 0000000..1e05637
--- /dev/null
+++ b/app/src/test/java/org/opencord/maclearner/app/impl/MacLearnerManagerTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-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.maclearner.app.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Set of tests of the Mac Learner ONOS application component.
+ */
+public class MacLearnerManagerTest extends TestBaseMacLearner {
+
+    @Before
+    public void setUp() {
+        setUpApp();
+    }
+
+    @After
+    public void tearDown() {
+        this.macLearnerManager.deactivate();
+    }
+
+    private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId CLIENT_VLAN = VlanId.vlanId("100");
+    private static final VlanId CLIENT_QINQ_VLAN = VlanId.vlanId("200");
+    private static final ConnectPoint CLIENT_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+
+    @Test
+    public void testSingleTagDhcpPacket() {
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT_MAC,
+                CLIENT_VLAN,
+                VlanId.NONE,
+                CLIENT_CP));
+        Optional<MacAddress> macAddress = macLearnerManager.getMacMapping(CLIENT_CP.deviceId(),
+                CLIENT_CP.port(), CLIENT_VLAN);
+        assertTrue(macAddress.isPresent());
+        assertEquals(CLIENT_MAC, macAddress.get());
+    }
+
+    @Test
+    public void testDoubleTagDhcpPacket() {
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT_MAC,
+                CLIENT_VLAN,
+                CLIENT_QINQ_VLAN,
+                CLIENT_CP));
+        Optional<MacAddress> macAddress = macLearnerManager.getMacMapping(CLIENT_CP.deviceId(),
+                CLIENT_CP.port(), CLIENT_QINQ_VLAN);
+        assertTrue(macAddress.isPresent());
+        assertEquals(CLIENT_MAC, macAddress.get());
+    }
+
+}
diff --git a/app/src/test/java/org/opencord/maclearner/app/impl/TestBaseMacLearner.java b/app/src/test/java/org/opencord/maclearner/app/impl/TestBaseMacLearner.java
new file mode 100644
index 0000000..c9d4af5
--- /dev/null
+++ b/app/src/test/java/org/opencord/maclearner/app/impl/TestBaseMacLearner.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2017-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.maclearner.app.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.DhcpOption;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.cfg.ComponentConfigService;
+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.net.ConnectPoint;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketContextAdapter;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+import org.onosproject.store.service.AsyncConsistentMap;
+import org.onosproject.store.service.AsyncDistributedSet;
+import org.onosproject.store.service.AtomicCounter;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.ConsistentMapAdapter;
+import org.onosproject.store.service.ConsistentMapBuilder;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.DistributedSetAdapter;
+import org.onosproject.store.service.DistributedSetBuilder;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.SetEventListener;
+import org.onosproject.store.service.StorageServiceAdapter;
+import org.onosproject.store.service.Versioned;
+
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiFunction;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Mac Learner mock services class.
+ */
+public abstract class TestBaseMacLearner {
+
+    private static final Ip4Address SERVER_IP = Ip4Address.valueOf("10.0.3.253");
+    private static final Ip4Address INTERFACE_IP = Ip4Address.valueOf("10.0.3.254");
+
+    protected MacLearnerManager macLearnerManager;
+    protected ObjectMapper mapper;
+    protected ApplicationId subject;
+
+    protected ComponentConfigService componentConfigService = new MockComponentConfigService();
+    protected MockCoreService coreService = new MockCoreService();
+    protected MockStorageService storageService = new MockStorageService();
+    protected MockPacketService packetService = new MockPacketService();
+
+    public void setUpApp() {
+        macLearnerManager = new MacLearnerManager();
+        macLearnerManager.componentConfigService = this.componentConfigService;
+        macLearnerManager.coreService = this.coreService;
+        macLearnerManager.storageService = this.storageService;
+        macLearnerManager.packetService = this.packetService;
+        injectEventDispatcher(macLearnerManager, new MockEventDispatcher());
+        mapper = new ObjectMapper();
+        subject = macLearnerManager.coreService.registerApplication("org.opencord.maclearner");
+
+        macLearnerManager.activate();
+    }
+
+    /**
+     * Mocks an instance of {@link ApplicationId} so that the application
+     * component under test can query and use its application ID.
+     */
+    private static final class MockApplicationId implements ApplicationId {
+
+        private final short id;
+        private final String name;
+
+        public MockApplicationId(short id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        @Override
+        public short id() {
+            return id;
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+    }
+
+    private static final class MockComponentConfigService extends ComponentConfigAdapter {
+
+    }
+
+    /**
+     * Mocks the core services of ONOS so that the application under test can
+     * register and query application IDs.
+     */
+    private static final class MockCoreService extends CoreServiceAdapter {
+
+        private List<ApplicationId> idList = Lists.newArrayList();
+        private Map<String, ApplicationId> idMap = Maps.newHashMap();
+
+        @Override
+        public ApplicationId getAppId(Short id) {
+            if (id >= idList.size()) {
+                return null;
+            }
+            return idList.get(id);
+        }
+
+        @Override
+        public ApplicationId getAppId(String name) {
+            return idMap.get(name);
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            ApplicationId appId = idMap.get(name);
+            if (appId == null) {
+                appId = new MockApplicationId((short) idList.size(), name);
+                idList.add(appId);
+                idMap.put(name, appId);
+            }
+            return appId;
+        }
+
+    }
+
+    /**
+     * Mocks the storage service of ONOS so that the application under test can
+     * use consistent maps.
+     */
+    private static class MockStorageService extends StorageServiceAdapter {
+
+        @Override
+        public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
+            ConsistentMapBuilder<K, V> builder = new ConsistentMapBuilder<K, V>() {
+                @Override
+                public AsyncConsistentMap<K, V> buildAsyncMap() {
+                    return null;
+                }
+
+                @Override
+                public ConsistentMap<K, V> build() {
+                    return new TestConsistentMap<>();
+                }
+            };
+
+            return builder;
+        }
+
+        @Override
+        public <E> DistributedSetBuilder<E> setBuilder() {
+            DistributedSetBuilder<E> builder = new DistributedSetBuilder<E>() {
+                @Override
+                public AsyncDistributedSet<E> build() {
+                    return new DistributedSetAdapter<E>() {
+                        @Override
+                        public DistributedSet<E> asDistributedSet() {
+                            return new TestDistributedSet<>();
+                        }
+                    };
+                }
+            };
+
+            return builder;
+        }
+
+        @Override
+        public AtomicCounter getAtomicCounter(String name) {
+            return new MockAtomicCounter();
+        }
+
+        // Mock ConsistentMap that behaves as a HashMap
+        class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
+            private Map<K, Versioned<V>> map = new HashMap<>();
+            private Map<MapEventListener<K, V>, Executor> listeners = new HashMap<>();
+
+            public void notifyListeners(MapEvent<K, V> event) {
+                listeners.forEach((c, e) -> e.execute(() -> c.event(event)));
+            }
+
+            @Override
+            public int size() {
+                return map.size();
+            }
+
+            @Override
+            public Versioned<V> put(K key, V value) {
+                Versioned<V> oldValue = map.get(key);
+                Versioned<V> newValue = new Versioned<>(value, oldValue == null ? 0 : oldValue.version() + 1);
+                map.put(key, newValue);
+                notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
+                return newValue;
+            }
+
+            @Override
+            public Versioned<V> get(K key) {
+                return map.get(key);
+            }
+
+            @Override
+            public Versioned<V> remove(K key) {
+                Versioned<V> oldValue = map.remove(key);
+                notifyListeners(new MapEvent<>(name(), key, oldValue, null));
+                return oldValue;
+            }
+
+            @Override
+            public Versioned<V> computeIfPresent(K key,
+                                                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                Versioned<V> oldValue = map.get(key);
+                Versioned<V> newValue = new Versioned<>(remappingFunction.apply(key, oldValue.value()),
+                        oldValue == null ? 0 : oldValue.version() + 1);
+                map.put(key, newValue);
+                notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
+                return newValue;
+            }
+
+            @Override
+            public Set<Map.Entry<K, Versioned<V>>> entrySet() {
+                return map.entrySet();
+            }
+
+            @Override
+            public Set<K> keySet() {
+                return map.keySet();
+            }
+
+            @Override
+            public Collection<Versioned<V>> values() {
+                return map.values();
+            }
+
+            @Override
+            public void clear() {
+                map.clear();
+            }
+
+            @Override
+            public void addListener(MapEventListener<K, V> listener, Executor executor) {
+                listeners.put(listener, executor);
+            }
+
+            @Override
+            public void removeListener(MapEventListener<K, V> listener) {
+                listeners.remove(listener);
+            }
+        }
+
+        // Mock DistributedSet that behaves as a HashSet
+        class TestDistributedSet<E> extends HashSet<E> implements DistributedSet<E> {
+
+            @Override
+            public void addListener(SetEventListener<E> listener) {
+            }
+
+            @Override
+            public void removeListener(SetEventListener<E> listener) {
+            }
+
+            @Override
+            public String name() {
+                return null;
+            }
+
+            @Override
+            public Type primitiveType() {
+                return null;
+            }
+        }
+    }
+
+    private static class MockAtomicCounter implements AtomicCounter {
+        long id = 0;
+
+        @Override
+        public long incrementAndGet() {
+            return ++id;
+        }
+
+        @Override
+        public long getAndIncrement() {
+            return id++;
+        }
+
+        @Override
+        public long getAndAdd(long delta) {
+            long oldId = id;
+            id += delta;
+            return oldId;
+        }
+
+        @Override
+        public long addAndGet(long delta) {
+            id += delta;
+            return id;
+        }
+
+        @Override
+        public void set(long value) {
+            id = value;
+        }
+
+        @Override
+        public boolean compareAndSet(long expectedValue, long updateValue) {
+            if (id == expectedValue) {
+                id = updateValue;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public long get() {
+            return id;
+        }
+
+        @Override
+        public String name() {
+            return "MockAtomicCounter";
+        }
+    }
+
+    /**
+     * Mocks the packet service of ONOS so that the application under test can
+     * observe network packets.
+     */
+    public static class MockPacketService extends PacketServiceAdapter {
+        Set<PacketProcessor> packetProcessors = Sets.newHashSet();
+        OutboundPacket emittedPacket;
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessors.add(processor);
+        }
+
+        public void processPacket(PacketContext packetContext) {
+            packetProcessors.forEach(p -> p.process(packetContext));
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            this.emittedPacket = packet;
+        }
+    }
+
+    /**
+     * Implements event delivery system that delivers events synchronously, or
+     * in-line with the post method invocation.
+     */
+    public static class MockEventDispatcher 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 void injectEventDispatcher(Object manager, EventDeliveryService svc) {
+        Class mc = manager.getClass();
+        Field[] var3 = mc.getSuperclass().getDeclaredFields();
+
+        for (Field f : var3) {
+            if (f.getType().equals(EventDeliveryService.class)) {
+                try {
+                    TestUtils.setField(manager, f.getName(), svc);
+                    break;
+                } catch (TestUtils.TestUtilsException var8) {
+                    throw new IllegalArgumentException("Unable to inject reference", var8);
+                }
+            }
+        }
+    }
+
+    /**
+     * Generates DHCP REQUEST packet.
+     */
+    protected static class TestDhcpRequestPacketContext extends PacketContextAdapter {
+
+        private InboundPacket inPacket;
+
+        public TestDhcpRequestPacketContext(MacAddress clientMac, VlanId vlanId,
+                                            VlanId qinqQVid,
+                                            ConnectPoint clientCp) {
+            super(0, null, null, false);
+            byte[] dhcpMsgType = new byte[1];
+            dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPREQUEST.getValue();
+
+            DhcpOption dhcpOption = new DhcpOption();
+            dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+            dhcpOption.setData(dhcpMsgType);
+            dhcpOption.setLength((byte) 1);
+            DhcpOption endOption = new DhcpOption();
+            endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+
+            DHCP dhcp = new DHCP();
+            dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
+            dhcp.setHardwareAddressLength((byte) 6);
+            dhcp.setClientHardwareAddress(clientMac.toBytes());
+            dhcp.setOptions(ImmutableList.of(dhcpOption, endOption));
+
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp);
+            udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
+            udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
+
+            IPv4 ipv4 = new IPv4();
+            ipv4.setPayload(udp);
+            ipv4.setDestinationAddress(SERVER_IP.toInt());
+            ipv4.setSourceAddress(INTERFACE_IP.toInt());
+
+            Ethernet eth = new Ethernet();
+            eth.setEtherType(Ethernet.TYPE_IPV4)
+                    .setVlanID(vlanId.toShort())
+                    .setQinQVID(qinqQVid.toShort())
+                    .setSourceMACAddress(clientMac)
+                    .setDestinationMACAddress(MacAddress.BROADCAST)
+                    .setPayload(ipv4);
+
+            this.inPacket = new DefaultInboundPacket(clientCp, eth,
+                    ByteBuffer.wrap(eth.serialize()));
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
+}
