diff --git a/web/api/src/test/java/org/onosproject/rest/DevicesResourceTest.java b/web/api/src/test/java/org/onosproject/rest/DevicesResourceTest.java
new file mode 100644
index 0000000..67b04c8
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/DevicesResourceTest.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2015 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.List;
+
+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.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceService;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.sun.jersey.api.client.UniformInterfaceException;
+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.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+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.junit.Assert.fail;
+import static org.onosproject.net.NetTestTools.device;
+import static org.onosproject.net.NetTestTools.did;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Unit tests for devices REST APIs.
+ */
+public class DevicesResourceTest extends JerseyTest {
+    DeviceService mockDeviceService;
+
+    /**
+     * Constructs the test.
+     */
+    public DevicesResourceTest() {
+        super("org.onosproject.rest");
+    }
+
+    /**
+     * Hamcrest matcher to check that an device representation in JSON matches
+     * the actual device.
+     */
+    public static class DeviceJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final Device device;
+        private String reason = "";
+
+        public DeviceJsonMatcher(Device deviceValue) {
+            device = deviceValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonDevice) {
+            // check id
+            String jsonId = jsonDevice.get("id").asString();
+            if (!jsonId.equals(device.id().toString())) {
+                reason = "id " + device.id().toString();
+                return false;
+            }
+
+            // check type
+            String jsonType = jsonDevice.get("type").asString();
+            if (!jsonType.equals(device.type().toString())) {
+                reason = "appId " + device.type().toString();
+                return false;
+            }
+
+            // check manufacturer
+            String jsonManufacturer = jsonDevice.get("mfr").asString();
+            if (!jsonManufacturer.equals(device.manufacturer())) {
+                reason = "manufacturer " + device.manufacturer();
+                return false;
+            }
+
+            // check HW version field
+            String jsonHwVersion = jsonDevice.get("hw").asString();
+            if (!jsonHwVersion.equals(device.hwVersion())) {
+                reason = "hw Version " + device.hwVersion();
+                return false;
+            }
+
+            // check SW version field
+            String jsonSwVersion = jsonDevice.get("sw").asString();
+            if (!jsonSwVersion.equals(device.swVersion())) {
+                reason = "sw Version " + device.swVersion();
+                return false;
+            }
+
+            // check serial number field
+            String jsonSerialNumber = jsonDevice.get("serial").asString();
+            if (!jsonSerialNumber.equals(device.serialNumber())) {
+                reason = "serial number " + device.serialNumber();
+                return false;
+            }
+
+            // check chassis id field
+            String jsonChassisId = jsonDevice.get("chassisId").asString();
+            if (!jsonChassisId.equals(device.chassisId().toString())) {
+                reason = "Chassis id " + device.chassisId().toString();
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate an device matcher.
+     *
+     * @param device device object we are looking for
+     * @return matcher
+     */
+    private static DeviceJsonMatcher matchesDevice(Device device) {
+        return new DeviceJsonMatcher(device);
+    }
+
+    /**
+     * Hamcrest matcher to check that an device is represented properly in a JSON
+     * array of devices.
+     */
+    private static class DeviceJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final Device device;
+        private String reason = "";
+
+        public DeviceJsonArrayMatcher(Device deviceValue) {
+            device = deviceValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            final int minExpectedAttributes = 9;
+            final int maxExpectedAttributes = 10;
+
+            boolean deviceFound = false;
+
+            for (int jsonDeviceIndex = 0; jsonDeviceIndex < json.size();
+                 jsonDeviceIndex++) {
+
+                JsonObject jsonDevice = json.get(jsonDeviceIndex).asObject();
+
+                if (jsonDevice.names().size() < minExpectedAttributes ||
+                    jsonDevice.names().size() > maxExpectedAttributes) {
+                    reason = "Found a device with the wrong number of attributes";
+                    return false;
+                }
+
+                String jsonDeviceId = jsonDevice.get("id").asString();
+                if (jsonDeviceId.equals(device.id().toString())) {
+                    deviceFound = true;
+
+                    //  We found the correct device, check attribute values
+                    assertThat(jsonDevice, matchesDevice(device));
+                }
+            }
+            if (!deviceFound) {
+                reason = "Device with id " + device.id().toString() + " not found";
+                return false;
+            } else {
+                return true;
+            }
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate an device array matcher.
+     *
+     * @param device device object we are looking for
+     * @return matcher
+     */
+    private static DeviceJsonArrayMatcher hasDevice(Device device) {
+        return new DeviceJsonArrayMatcher(device);
+    }
+
+    @Before
+    public void setUp() {
+        mockDeviceService = createMock(DeviceService.class);
+
+        expect(mockDeviceService.isAvailable(isA(DeviceId.class)))
+                .andReturn(true)
+                .anyTimes();
+        expect(mockDeviceService.getRole(isA(DeviceId.class)))
+                .andReturn(MastershipRole.MASTER)
+                .anyTimes();
+
+        // Register the services needed for the test
+        CodecManager codecService =  new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(DeviceService.class, mockDeviceService)
+                        .add(CodecService.class, codecService);
+
+        BaseResource.setServiceDirectory(testDirectory);
+
+
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+        verify(mockDeviceService);
+    }
+
+    /**
+     * Tests the result of the rest api GET when there are no devices.
+     */
+    @Test
+    public void testDevicesEmptyArray() {
+        expect(mockDeviceService.getDevices()).andReturn(ImmutableList.of());
+        replay(mockDeviceService);
+
+        WebResource rs = resource();
+        String response = rs.path("devices").get(String.class);
+        assertThat(response, is("{\"devices\":[]}"));
+    }
+
+    /**
+     * Tests the result of the rest api GET when there are devices present.
+     */
+    @Test
+    public void testDevices() {
+        Device device1 = device("dev1");
+        Device device2 = device("dev2");
+        Device device3 = device("dev3");
+
+        expect(mockDeviceService.getDevices())
+                .andReturn(ImmutableList.of(device1, device2, device3))
+                .anyTimes();
+
+        replay(mockDeviceService);
+
+        WebResource rs = resource();
+        String response = rs.path("devices").get(String.class);
+        assertThat(response, containsString("{\"devices\":["));
+
+        JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("devices"));
+
+        JsonArray jsonDevices = result.get("devices").asArray();
+        assertThat(jsonDevices, notNullValue());
+        assertThat(jsonDevices.size(), is(3));
+
+        assertThat(jsonDevices, hasDevice(device1));
+        assertThat(jsonDevices, hasDevice(device2));
+        assertThat(jsonDevices, hasDevice(device3));
+    }
+
+    /**
+     * Tests the result of a rest api GET for a single device.
+     */
+    @Test
+    public void testDevicesSingle() {
+
+        String deviceIdString = "testdevice";
+        DeviceId deviceId = did(deviceIdString);
+        Device device = device(deviceIdString);
+
+        expect(mockDeviceService.getDevice(deviceId))
+                .andReturn(device)
+                .once();
+        replay(mockDeviceService);
+
+        WebResource rs = resource();
+        String response = rs.path("devices/" + deviceId).get(String.class);
+        JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, matchesDevice(device));
+    }
+
+    /**
+     * Tests the result of a rest api GET for the ports of a single device.
+     */
+    @Test
+    public void testDeviceAndPorts() {
+
+        String deviceIdString = "testdevice";
+        DeviceId deviceId = did(deviceIdString);
+        Device device = device(deviceIdString);
+
+        Port port1 = new DefaultPort(device, portNumber(1), true);
+        Port port2 = new DefaultPort(device, portNumber(2), true);
+        Port port3 = new DefaultPort(device, portNumber(3), true);
+        List<Port> ports = ImmutableList.of(port1, port2, port3);
+
+        expect(mockDeviceService.getDevice(deviceId))
+                .andReturn(device)
+                .once();
+
+        expect(mockDeviceService.getPorts(deviceId))
+                .andReturn(ports)
+                .once();
+        replay(mockDeviceService);
+
+        WebResource rs = resource();
+        String response =
+                rs.path("devices/" + deviceId + "/ports")
+                    .get(String.class);
+        JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, matchesDevice(device));
+
+        JsonArray jsonPorts = result.get("ports").asArray();
+        assertThat(jsonPorts.size(), is(3));
+        for (int portIndex = 0; portIndex < jsonPorts.size(); portIndex++) {
+            JsonObject jsonPort = jsonPorts.get(portIndex).asObject();
+
+            assertThat(jsonPort.size(), is(4));
+            assertThat(jsonPort.get("port").asString(),
+                       is(Integer.toString(portIndex + 1)));
+            assertThat(jsonPort.get("isEnabled").asBoolean(),
+                       is(true));
+            assertThat(jsonPort.get("type").asString(),
+                       equalTo("copper"));
+            assertThat(jsonPort.get("portSpeed").asLong(),
+                    is(1000L));
+        }
+    }
+
+    /**
+     * Tests that a fetch of a non-existent device object throws an exception.
+     */
+    @Test
+    public void testBadGet() {
+
+        expect(mockDeviceService.getDevice(isA(DeviceId.class)))
+                .andReturn(null)
+                .anyTimes();
+        replay(mockDeviceService);
+
+        WebResource rs = resource();
+        try {
+            rs.path("devices/0").get(String.class);
+            fail("Fetch of non-existent device did not throw an exception");
+        } catch (UniformInterfaceException ex) {
+            assertThat(ex.getMessage(),
+                    containsString("returned a response status of"));
+        }
+    }
+}
