diff --git a/web/api/src/test/java/org/onosproject/rest/HostResourceTest.java b/web/api/src/test/java/org/onosproject/rest/HostResourceTest.java
new file mode 100644
index 0000000..2a7a162
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/HostResourceTest.java
@@ -0,0 +1,333 @@
+/*
+ * 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.rest;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.provider.ProviderId;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableSet;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.test.framework.JerseyTest;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.onlab.packet.MacAddress.valueOf;
+import static org.onlab.packet.VlanId.vlanId;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Simple example on how to write a JAX-RS unit test using Jersey test framework.
+ * A base class should/will be created to provide further assistance for testing.
+ */
+public class HostResourceTest extends JerseyTest {
+    final HostService mockHostService = createMock(HostService.class);
+    final HashSet<Host> hosts = new HashSet<>();
+
+    public HostResourceTest() {
+        super("org.onosproject.rest");
+    }
+
+    @Before
+    public void setUp() {
+        expect(mockHostService.getHosts()).andReturn(hosts).anyTimes();
+
+        // Register the services needed for the test
+        final CodecManager codecService =  new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(HostService.class, mockHostService)
+                        .add(CodecService.class, codecService);
+
+        BaseResource.setServiceDirectory(testDirectory);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+        verify(mockHostService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a host representation in JSON matches
+     * the actual host.
+     */
+    public static class HostJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final Host host;
+        private String reason = "";
+
+        public HostJsonMatcher(Host hostValue) {
+            host = hostValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            // Check id
+            final String jsonId = jsonHost.get("id").asString();
+            if (!jsonId.equals(host.id().toString())) {
+                reason = "id " + host.id().toString();
+                return false;
+            }
+
+            // Check vlan id
+            final String jsonVlanId = jsonHost.get("vlan").asString();
+            if (!jsonVlanId.equals(host.vlan().toString())) {
+                reason = "vlan id " + host.vlan().toString();
+                return false;
+            }
+
+            // Check mac address
+            final String jsonMacAddress = jsonHost.get("mac").asString();
+            if (!jsonMacAddress.equals(host.mac().toString())) {
+                reason = "mac address " + host.mac().toString();
+                return false;
+            }
+
+            // Check location element id
+            final JsonObject jsonLocation = jsonHost.get("location").asObject();
+            final String jsonLocationElementId = jsonLocation.get("elementId").asString();
+            if (!jsonLocationElementId.equals(host.location().elementId().toString())) {
+                reason = "location element id " + host.location().elementId().toString();
+                return false;
+            }
+
+            // Check location port number
+            final String jsonLocationPortNumber = jsonLocation.get("port").asString();
+            if (!jsonLocationPortNumber.equals(host.location().port().toString())) {
+                reason = "location portNumber " + host.location().port().toString();
+                return false;
+            }
+
+            //  Check Ip Addresses
+            final JsonArray jsonHostIps = jsonHost.get("ipAddresses").asArray();
+            final Set<IpAddress> expectedHostIps = host.ipAddresses();
+            if (jsonHostIps.size() != expectedHostIps.size()) {
+                reason = "IP address arrays differ in size";
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a host array matcher.
+     *
+     * @param host host object we are looking for
+     * @return matcher
+     */
+    private static HostJsonMatcher matchesHost(Host host) {
+        return new HostJsonMatcher(host);
+    }
+
+    /**
+     * Hamcrest matcher to check that a host is represented properly in a JSON
+     * array of hosts.
+     */
+    public static class HostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final Host host;
+        private String reason = "";
+
+        public HostJsonArrayMatcher(Host hostValue) {
+            host = hostValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean hostFound = false;
+            final int expectedAttributes = 5;
+            for (int jsonHostIndex = 0; jsonHostIndex < json.size();
+                 jsonHostIndex++) {
+
+                final JsonObject jsonHost = json.get(jsonHostIndex).asObject();
+
+                if (jsonHost.names().size() != expectedAttributes) {
+                    reason = "Found a host with the wrong number of attributes";
+                    return false;
+                }
+
+                final String jsonHostId = jsonHost.get("id").asString();
+                if (jsonHostId.equals(host.id().toString())) {
+                    hostFound = true;
+
+                    //  We found the correct host, check attribute values
+                    assertThat(jsonHost, matchesHost(host));
+                }
+            }
+            if (!hostFound) {
+                reason = "Host with id " + host.id().toString() + " not found";
+                return false;
+            } else {
+                return true;
+            }
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a host array matcher.
+     *
+     * @param host host object we are looking for
+     * @return matcher
+     */
+    private static HostJsonArrayMatcher hasHost(Host host) {
+        return new HostJsonArrayMatcher(host);
+    }
+
+    /**
+     * Tests the result of the rest api GET when there are no hosts.
+     */
+    @Test
+    public void testHostsEmptyArray() {
+        replay(mockHostService);
+        WebResource rs = resource();
+        String response = rs.path("hosts").get(String.class);
+        assertThat(response, is("{\"hosts\":[]}"));
+    }
+
+    /**
+     * Tests the result of the rest api GET when hosts are defined.
+     */
+    @Test
+    public void testHostsArray() {
+        replay(mockHostService);
+        final ProviderId pid = new ProviderId("of", "foo");
+        final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
+        final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
+        final Host host1 =
+                new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
+                        new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
+                        ips1);
+        final MacAddress mac2 = MacAddress.valueOf("00:00:11:00:00:02");
+        final Set<IpAddress> ips2 = ImmutableSet.of(
+                IpAddress.valueOf("2222:2222:2222:1::"),
+                IpAddress.valueOf("2222:2222:2222:2::"));
+        final Host host2 =
+                new DefaultHost(pid, HostId.hostId(mac2), valueOf(2), vlanId((short) 2),
+                        new HostLocation(DeviceId.deviceId("2"), portNumber(22), 2),
+                        ips2);
+        hosts.add(host1);
+        hosts.add(host2);
+        WebResource rs = resource();
+        String response = rs.path("hosts").get(String.class);
+        assertThat(response, containsString("{\"hosts\":["));
+
+        final JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("hosts"));
+
+        final JsonArray hosts = result.get("hosts").asArray();
+        assertThat(hosts, notNullValue());
+
+        assertThat(hosts, hasHost(host1));
+        assertThat(hosts, hasHost(host2));
+    }
+
+    /**
+     * Tests fetch of one host by Id.
+     */
+    @Test
+    public void testSingleHostByIdFetch() {
+        final ProviderId pid = new ProviderId("of", "foo");
+        final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
+        final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
+        final Host host1 =
+                new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
+                        new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
+                        ips1);
+
+        hosts.add(host1);
+
+        expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
+                .andReturn(host1)
+                .anyTimes();
+        replay(mockHostService);
+
+        WebResource rs = resource();
+        String response = rs.path("hosts/00:00:11:00:00:01%2F1").get(String.class);
+        final JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, matchesHost(host1));
+    }
+
+    /**
+     * Tests fetch of one host by mac and vlan.
+     */
+    @Test
+    public void testSingleHostByMacAndVlanFetch() {
+        final ProviderId pid = new ProviderId("of", "foo");
+        final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
+        final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
+        final Host host1 =
+                new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
+                        new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
+                        ips1);
+
+        hosts.add(host1);
+
+        expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
+                .andReturn(host1)
+                .anyTimes();
+        replay(mockHostService);
+
+        WebResource rs = resource();
+        String response = rs.path("hosts/00:00:11:00:00:01/1").get(String.class);
+        final JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, matchesHost(host1));
+    }
+
+}
+
