diff --git a/apps/onos-app-dhcp/src/test/java/org/onosproject/dhcp/IPAssignmentTest.java b/apps/onos-app-dhcp/src/test/java/org/onosproject/dhcp/IPAssignmentTest.java
new file mode 100644
index 0000000..0783ec7
--- /dev/null
+++ b/apps/onos-app-dhcp/src/test/java/org/onosproject/dhcp/IPAssignmentTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * 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.onosproject.dhcp;
+
+import com.google.common.testing.EqualsTester;
+import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+
+import java.util.Date;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit Tests for IPAssignment class.
+ */
+public class IPAssignmentTest extends TestCase {
+
+    private final Date dateNow = new Date();
+
+    private final IPAssignment stats1 = IPAssignment.builder()
+            .ipAddress(Ip4Address.valueOf("10.10.10.10"))
+            .leasePeriod(300)
+            .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired)
+            .timestamp(dateNow)
+            .build();
+
+    private final IPAssignment stats2 = IPAssignment.builder()
+            .ipAddress(Ip4Address.valueOf("10.10.10.10"))
+            .leasePeriod(300)
+            .assignmentStatus(IPAssignment.AssignmentStatus.Option_Assigned)
+            .timestamp(dateNow)
+            .build();
+
+    private final IPAssignment stats3 = IPAssignment.builder(stats1)
+            .build();
+
+    /**
+     *  Tests the constructor for the class.
+     */
+    @Test
+    public void testConstruction() {
+        assertThat(stats3.ipAddress(), is(Ip4Address.valueOf("10.10.10.10")));
+        assertThat(stats3.timestamp(), is(dateNow));
+        assertThat(stats3.leasePeriod(), is(300));
+        assertThat(stats3.assignmentStatus(), is(IPAssignment.AssignmentStatus.Option_Expired));
+    }
+
+    /**
+     * Tests the equality and inequality of objects using Guava EqualsTester.
+     */
+    @Test
+    public void testEquals() {
+        new EqualsTester()
+                .addEqualityGroup(stats1, stats1)
+                .addEqualityGroup(stats2)
+                .testEquals();
+    }
+
+    /**
+     * Tests if the toString method returns a consistent value for hashing.
+     */
+    @Test
+    public void testToString() {
+        assertThat(stats1.toString(), is(stats1.toString()));
+    }
+
+    /**
+     * Tests if the validateInputs method returns an exception for malformed object.
+     */
+    @Test
+    public void testValidateInputs() {
+        try {
+            IPAssignment stats4 = IPAssignment.builder()
+                    .ipAddress(Ip4Address.valueOf("10.10.10.10"))
+                    .leasePeriod(300)
+                    .build();
+
+            fail("Construction of a malformed IPAssignment did not throw an exception");
+        } catch (NullPointerException e) {
+            Assert.assertThat(e.getMessage(), containsString("must be specified"));
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/onos-app-dhcp/src/test/java/org/onosproject/dhcp/impl/DHCPManagerTest.java b/apps/onos-app-dhcp/src/test/java/org/onosproject/dhcp/impl/DHCPManagerTest.java
new file mode 100644
index 0000000..3eda1bc
--- /dev/null
+++ b/apps/onos-app-dhcp/src/test/java/org/onosproject/dhcp/impl/DHCPManagerTest.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * 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.onosproject.dhcp.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.DHCPOption;
+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.onosproject.core.CoreServiceAdapter;
+import org.onosproject.dhcp.DHCPStore;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.provider.ProviderId;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.NetTestTools.connectPoint;
+
+/**
+ * Set of tests of the ONOS application component.
+ */
+
+public class DHCPManagerTest {
+
+    private DHCPManager dhcpManager;
+
+    protected PacketProcessor packetProcessor;
+
+    protected HostProviderService hostProviderService;
+
+    private static final MacAddress CLIENT1_MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
+
+    private static final String EXPECTED_IP = "10.2.0.2";
+
+    private static final Ip4Address BROADCAST = Ip4Address.valueOf("255.255.255.255");
+
+    private static final int TRANSACTION_ID = 1000;
+
+    private static final ProviderId PID = new ProviderId("of", "foo");
+
+    @Before
+    public void setUp() {
+        dhcpManager = new DHCPManager();
+        dhcpManager.cfgService = new TestNetworkConfigRegistry();
+        dhcpManager.packetService = new TestPacketService();
+        dhcpManager.coreService = new TestCoreService();
+        dhcpManager.dhcpStore = new TestDHCPStore();
+        hostProviderService = new TestHostProviderService(new TestHostProvider());
+        dhcpManager.hostProviderService = hostProviderService;
+        dhcpManager.hostProviderRegistry = new TestHostRegistry();
+        dhcpManager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        dhcpManager.deactivate();
+    }
+
+    /**
+     * Tests the response to a DHCP Discover Packet.
+     */
+    @Test
+    public void testDiscover() {
+        Ethernet reply = constructDHCPPacket(DHCP.DHCPMessageType.MessageType_Discover);
+        sendPacket(reply);
+    }
+
+    /**
+     * Tests the response to a DHCP Request Packet.
+     */
+    @Test
+    public void testRequest() {
+        Ethernet reply = constructDHCPPacket(DHCP.DHCPMessageType.MessageType_Request);
+        sendPacket(reply);
+    }
+
+    /**
+     * Sends an Ethernet packet to the process method of the Packet Processor.
+     * @param reply Ethernet packet
+     */
+    private void sendPacket(Ethernet reply) {
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
+        InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
+                reply,
+                byteBuffer);
+
+        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+        packetProcessor.process(context);
+    }
+
+    /**
+     * Constructs an Ethernet packet containing a DHCP Payload.
+     * @param messageType DHCP Message Type
+     * @return Ethernet packet
+     */
+    private Ethernet constructDHCPPacket(DHCP.DHCPMessageType messageType) {
+
+        // Ethernet Frame.
+        Ethernet ethReply = new Ethernet();
+        ethReply.setSourceMACAddress(CLIENT1_MAC);
+        ethReply.setDestinationMACAddress(MacAddress.BROADCAST);
+        ethReply.setEtherType(Ethernet.TYPE_IPV4);
+        ethReply.setVlanID((short) 2);
+
+        // IP Packet
+        IPv4 ipv4Reply = new IPv4();
+        ipv4Reply.setSourceAddress(0);
+        ipv4Reply.setDestinationAddress(BROADCAST.toInt());
+        ipv4Reply.setTtl((byte) 127);
+
+        // UDP Datagram.
+        UDP udpReply = new UDP();
+        udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
+        udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
+
+        // DHCP Payload.
+        DHCP dhcpReply = new DHCP();
+        dhcpReply.setOpCode(DHCP.OPCODE_REQUEST);
+
+        dhcpReply.setYourIPAddress(0);
+        dhcpReply.setServerIPAddress(0);
+
+        dhcpReply.setTransactionId(TRANSACTION_ID);
+        dhcpReply.setClientHardwareAddress(CLIENT1_MAC.toBytes());
+        dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
+        dhcpReply.setHardwareAddressLength((byte) 6);
+
+        // DHCP Options.
+        DHCPOption option = new DHCPOption();
+        List<DHCPOption> optionList = new ArrayList<>();
+
+        // DHCP Message Type.
+        option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+        option.setLength((byte) 1);
+        byte[] optionData = {messageType.getValue()};
+        option.setData(optionData);
+        optionList.add(option);
+
+        // DHCP Requested IP.
+        option = new DHCPOption();
+        option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
+        option.setLength((byte) 4);
+        optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
+        option.setData(optionData);
+        optionList.add(option);
+
+        // End Option.
+        option = new DHCPOption();
+        option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+        option.setLength((byte) 1);
+        optionList.add(option);
+
+        dhcpReply.setOptions(optionList);
+
+        udpReply.setPayload(dhcpReply);
+        ipv4Reply.setPayload(udpReply);
+        ethReply.setPayload(ipv4Reply);
+
+        return ethReply;
+    }
+
+    /**
+     * Validates the contents of the packet sent by the DHCP Manager.
+     * @param packet Ethernet packet received
+     */
+    private void validatePacket(Ethernet packet) {
+        DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload();
+        assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_MAC);
+        assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP));
+        assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID);
+    }
+
+    /**
+     * Mocks the DHCPStore.
+     */
+    private final class TestDHCPStore implements DHCPStore {
+
+
+        public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) {
+        }
+
+        public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) {
+            return Ip4Address.valueOf(EXPECTED_IP);
+        }
+
+        public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) {
+            return true;
+        }
+
+        public void setDefaultTimeoutForPurge(int timeInSeconds) {
+        }
+
+        public void setTimerDelay(int timeInSeconds) {
+        }
+
+        public void releaseIP(MacAddress macID) {
+        }
+
+        public Map<MacAddress, Ip4Address> listMapping() {
+            Map<MacAddress, Ip4Address> map = new HashMap<>();
+            map.put(CLIENT1_MAC, Ip4Address.valueOf(EXPECTED_IP));
+            return map;
+        }
+
+        public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) {
+            return true;
+        }
+
+        public boolean removeStaticIP(MacAddress macID) {
+            return true;
+        }
+
+        public Iterable<Ip4Address> getAvailableIPs() {
+            List<Ip4Address> ipList = new ArrayList<>();
+            ipList.add(Ip4Address.valueOf(EXPECTED_IP));
+            return ImmutableSet.copyOf(ipList);
+        }
+    }
+
+    /**
+     * Mocks the DefaultPacket context.
+     */
+    private final class TestPacketContext extends DefaultPacketContext {
+        private TestPacketContext(long time, InboundPacket inPkt,
+                                    OutboundPacket outPkt, boolean block) {
+            super(time, inPkt, outPkt, block);
+        }
+
+        @Override
+        public void send() {
+            // We don't send anything out.
+        }
+    }
+
+    /**
+     * Keeps a reference to the PacketProcessor and verifies the OutboundPackets.
+     */
+    private class TestPacketService extends PacketServiceAdapter {
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            try {
+                Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
+                        0, packet.data().array().length);
+                validatePacket(eth);
+            } catch (Exception e) {
+                fail(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Mocks the CoreService.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+    }
+
+    /**
+     * Mocks the NetworkConfigRegistry.
+     */
+    private class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
+
+    }
+
+    /**
+     * Mocks the HostProviderService.
+     */
+    private class TestHostProviderService extends AbstractProviderService<HostProvider>
+            implements HostProviderService {
+
+        protected TestHostProviderService(HostProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void hostDetected(HostId hostId, HostDescription hostDescription) {
+        }
+
+        @Override
+        public void hostVanished(HostId hostId) {
+        }
+
+    }
+
+    /**
+     * Mocks the HostProvider.
+     */
+    private static class TestHostProvider extends AbstractProvider
+            implements HostProvider {
+
+        protected TestHostProvider() {
+            super(PID);
+        }
+
+        @Override
+        public ProviderId id() {
+            return PID;
+        }
+
+        @Override
+        public void triggerProbe(Host host) {
+        }
+
+    }
+
+    /**
+     * Mocks the HostProviderRegistry.
+     */
+    private class TestHostRegistry implements HostProviderRegistry {
+
+        @Override
+        public HostProviderService register(HostProvider provider) {
+            return hostProviderService;
+        }
+
+        @Override
+        public void unregister(HostProvider provider) {
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return null;
+        }
+
+    }
+
+}
