diff --git a/web/api/src/test/java/org/onosproject/rest/resources/GroupsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/GroupsResourceTest.java
new file mode 100644
index 0000000..1321893
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/resources/GroupsResourceTest.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2014-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.resources;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableSet;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+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.codec.impl.GroupCodec;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupService;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyShort;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.onosproject.net.NetTestTools.APP_ID;
+
+/**
+ * Unit tests for Groups REST APIs.
+ */
+public class GroupsResourceTest extends ResourceTest {
+    final GroupService mockGroupService = createMock(GroupService.class);
+    CoreService mockCoreService = createMock(CoreService.class);
+    final DeviceService mockDeviceService = createMock(DeviceService.class);
+
+    final HashMap<DeviceId, Set<Group>> groups = new HashMap<>();
+
+
+    final DeviceId deviceId1 = DeviceId.deviceId("1");
+    final DeviceId deviceId2 = DeviceId.deviceId("2");
+    final DeviceId deviceId3 = DeviceId.deviceId("3");
+    final Device device1 = new DefaultDevice(null, deviceId1, Device.Type.OTHER,
+            "", "", "", "", null);
+    final Device device2 = new DefaultDevice(null, deviceId2, Device.Type.OTHER,
+            "", "", "", "", null);
+
+    final MockGroup group1 = new MockGroup(deviceId1, 1, "111", 1);
+    final MockGroup group2 = new MockGroup(deviceId1, 2, "222", 2);
+
+    final MockGroup group3 = new MockGroup(deviceId2, 3, "333", 3);
+    final MockGroup group4 = new MockGroup(deviceId2, 4, "444", 4);
+
+    final MockGroup group5 = new MockGroup(deviceId3, 5, "555", 5);
+    final MockGroup group6 = new MockGroup(deviceId3, 6, "666", 6);
+
+    /**
+     * Mock class for a group.
+     */
+    private static class MockGroup implements Group {
+
+        final DeviceId deviceId;
+        final ApplicationId appId;
+        final GroupKey appCookie;
+        final long baseValue;
+        final List<GroupBucket> bucketList;
+        GroupBuckets buckets;
+
+        public MockGroup(DeviceId deviceId, int appId, String appCookie, int id) {
+            this.deviceId = deviceId;
+            this.appId = new DefaultApplicationId(appId, String.valueOf(appId));
+            this.appCookie = new DefaultGroupKey(appCookie.getBytes());
+            this.baseValue = id * 100;
+            this.bucketList = new ArrayList<>();
+            this.buckets = new GroupBuckets(bucketList);
+        }
+
+        @Override
+        public GroupId id() {
+            return new DefaultGroupId((int) baseValue + 55);
+        }
+
+        @Override
+        public GroupState state() {
+            return GroupState.ADDED;
+        }
+
+        @Override
+        public long life() {
+            return baseValue + 11;
+        }
+
+        @Override
+        public long packets() {
+            return baseValue + 22;
+        }
+
+        @Override
+        public long bytes() {
+            return baseValue + 33;
+        }
+
+        @Override
+        public long referenceCount() {
+            return baseValue + 44;
+        }
+
+        @Override
+        public Type type() {
+            return GroupDescription.Type.ALL;
+        }
+
+        @Override
+        public DeviceId deviceId() {
+            return this.deviceId;
+        }
+
+        @Override
+        public ApplicationId appId() {
+            return this.appId;
+        }
+
+        @Override
+        public GroupKey appCookie() {
+            return this.appCookie;
+        }
+
+        @Override
+        public Integer givenGroupId() {
+            return (int) baseValue + 55;
+        }
+
+        @Override
+        public GroupBuckets buckets() {
+            return this.buckets;
+        }
+    }
+
+    /**
+     * Populates some groups used as testing data.
+     */
+    private void setupMockGroups() {
+        final Set<Group> groups1 = new HashSet<>();
+        groups1.add(group1);
+        groups1.add(group2);
+
+        final Set<Group> groups2 = new HashSet<>();
+        groups2.add(group3);
+        groups2.add(group4);
+
+        groups.put(deviceId1, groups1);
+        groups.put(deviceId2, groups2);
+
+        expect(mockGroupService.getGroups(deviceId1))
+                .andReturn(groups.get(deviceId1)).anyTimes();
+        expect(mockGroupService.getGroups(deviceId2))
+                .andReturn(groups.get(deviceId2)).anyTimes();
+    }
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Mock device service
+        expect(mockDeviceService.getDevice(deviceId1))
+                .andReturn(device1);
+        expect(mockDeviceService.getDevice(deviceId2))
+                .andReturn(device2);
+        expect(mockDeviceService.getDevices())
+                .andReturn(ImmutableSet.of(device1, device2));
+
+        // Mock Core Service
+        expect(mockCoreService.getAppId(anyShort()))
+                .andReturn(NetTestTools.APP_ID).anyTimes();
+        expect(mockCoreService.registerApplication(GroupCodec.REST_APP_ID))
+                .andReturn(APP_ID).anyTimes();
+        replay(mockCoreService);
+
+        // Register the services needed for the test
+        final CodecManager codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(GroupService.class, mockGroupService)
+                        .add(DeviceService.class, mockDeviceService)
+                        .add(CodecService.class, codecService)
+                        .add(CoreService.class, mockCoreService);
+
+        BaseResource.setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Cleans up and verifies the mocks.
+     */
+    @After
+    public void tearDownTest() {
+        verify(mockGroupService);
+        verify(mockCoreService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a group representation in JSON matches
+     * the actual group.
+     */
+    public static class GroupJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final Group group;
+        private final String expectedAppId;
+        private String reason = "";
+
+        public GroupJsonMatcher(Group groupValue, String expectedAppIdValue) {
+            group = groupValue;
+            expectedAppId = expectedAppIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonGroup) {
+            // check id
+            final String jsonId = jsonGroup.get("id").asString();
+            final String groupId = group.id().toString();
+            if (!jsonId.equals(groupId)) {
+                reason = "id " + group.id().toString();
+                return false;
+            }
+
+            // check application id
+            final String jsonAppId = jsonGroup.get("appId").asString();
+            final String appId = group.appId().toString();
+            if (!jsonAppId.equals(appId)) {
+                reason = "appId " + group.appId().toString();
+                return false;
+            }
+
+            // check device id
+            final String jsonDeviceId = jsonGroup.get("deviceId").asString();
+            if (!jsonDeviceId.equals(group.deviceId().toString())) {
+                reason = "deviceId " + group.deviceId();
+                return false;
+            }
+
+            // check bucket array
+            if (group.buckets().buckets() != null) {
+                final JsonArray jsonBuckets = jsonGroup.get("buckets").asArray();
+                if (group.buckets().buckets().size() != jsonBuckets.size()) {
+                    reason = "buckets array size of " +
+                            Integer.toString(group.buckets().buckets().size());
+                    return false;
+                }
+                for (final GroupBucket groupBucket : group.buckets().buckets()) {
+                    boolean groupBucketFound = false;
+                    for (int groupBucketIndex = 0; groupBucketIndex < jsonBuckets.size(); groupBucketIndex++) {
+                        final String jsonType = jsonBuckets.get(groupBucketIndex).asObject().get("type").asString();
+                        final String bucketType = groupBucket.type().name();
+                        if (jsonType.equals(bucketType)) {
+                            groupBucketFound = true;
+                        }
+                    }
+                    if (!groupBucketFound) {
+                        reason = "group bucket " + groupBucket.toString();
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a group matcher.
+     *
+     * @param group group object we are looking for
+     * @return matcher
+     */
+    private static GroupJsonMatcher matchesGroup(Group group, String expectedAppName) {
+        return new GroupJsonMatcher(group, expectedAppName);
+    }
+
+    /**
+     * Hamcrest matcher to check that a group is represented properly in a JSON
+     * array of flows.
+     */
+    public static class GroupJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final Group group;
+        private String reason = "";
+
+        public GroupJsonArrayMatcher(Group groupValue) {
+            group = groupValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean groupFound = false;
+            for (int jsonGroupIndex = 0; jsonGroupIndex < json.size();
+                 jsonGroupIndex++) {
+
+                final JsonObject jsonGroup = json.get(jsonGroupIndex).asObject();
+
+                final String groupId = group.id().toString();
+                final String jsonGroupId = jsonGroup.get("id").asString();
+                if (jsonGroupId.equals(groupId)) {
+                    groupFound = true;
+
+                    //  We found the correct group, check attribute values
+                    assertThat(jsonGroup, matchesGroup(group, APP_ID.name()));
+                }
+            }
+            if (!groupFound) {
+                reason = "Group with id " + group.id().toString() + " not found";
+                return false;
+            } else {
+                return true;
+            }
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a group array matcher.
+     *
+     * @param group group object we are looking for
+     * @return matcher
+     */
+    private static GroupJsonArrayMatcher hasGroup(Group group) {
+        return new GroupJsonArrayMatcher(group);
+    }
+
+    /**
+     * Tests the result of the rest api GET when there are no groups.
+     */
+    @Test
+    public void testGroupsEmptyArray() {
+        expect(mockGroupService.getGroups(deviceId1)).andReturn(null).anyTimes();
+        expect(mockGroupService.getGroups(deviceId2)).andReturn(null).anyTimes();
+        replay(mockGroupService);
+        replay(mockDeviceService);
+        final WebTarget wt = target();
+        final String response = wt.path("groups").request().get(String.class);
+        assertThat(response, is("{\"groups\":[]}"));
+    }
+
+    /**
+     * Tests the result of the rest api GET when there are active groups.
+     */
+    @Test
+    public void testGroupsPopulatedArray() {
+        setupMockGroups();
+        replay(mockGroupService);
+        replay(mockDeviceService);
+        final WebTarget wt = target();
+        final String response = wt.path("groups").request().get(String.class);
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("groups"));
+        final JsonArray jsonGroups = result.get("groups").asArray();
+        assertThat(jsonGroups, notNullValue());
+        assertThat(jsonGroups, hasGroup(group1));
+        assertThat(jsonGroups, hasGroup(group2));
+        assertThat(jsonGroups, hasGroup(group3));
+        assertThat(jsonGroups, hasGroup(group4));
+    }
+
+    /**
+     * Tests the result of a rest api GET for a device.
+     */
+    @Test
+    public void testGroupsSingleDevice() {
+        setupMockGroups();
+        final Set<Group> groups = new HashSet<>();
+        groups.add(group5);
+        groups.add(group6);
+        expect(mockGroupService.getGroups(anyObject()))
+                .andReturn(groups).anyTimes();
+        replay(mockGroupService);
+        replay(mockDeviceService);
+        final WebTarget wt = target();
+        final String response = wt.path("groups/" + deviceId3).request().get(String.class);
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("groups"));
+        final JsonArray jsonGroups = result.get("groups").asArray();
+        assertThat(jsonGroups, notNullValue());
+        assertThat(jsonGroups, hasGroup(group5));
+        assertThat(jsonGroups, hasGroup(group6));
+    }
+
+    /**
+     * Test the result of a rest api GET with specifying device id and appcookie.
+     */
+    @Test
+    public void testGroupByDeviceIdAndAppCookie() {
+        setupMockGroups();
+        expect(mockGroupService.getGroup(anyObject(), anyObject()))
+                .andReturn(group5).anyTimes();
+        replay(mockGroupService);
+        final WebTarget wt = target();
+        final String response = wt.path("groups/" + deviceId3 + "/" + "111")
+                .request().get(String.class);
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("groups"));
+        final JsonArray jsonFlows = result.get("groups").asArray();
+        assertThat(jsonFlows, notNullValue());
+        assertThat(jsonFlows, hasGroup(group5));
+    }
+
+    /**
+     * Test whether the REST API returns 404 if no entry has been found.
+     */
+    @Test
+    public void testGroupByDeviceIdAndAppCookieNull() {
+        setupMockGroups();
+        expect(mockGroupService.getGroup(anyObject(), anyObject()))
+                .andReturn(null).anyTimes();
+        replay(mockGroupService);
+        final WebTarget wt = target();
+        final Response response = wt.path("groups/" + deviceId3 + "/" + "222").request().get();
+
+        assertEquals(404, response.getStatus());
+    }
+
+    /**
+     * Tests creating a group with POST.
+     */
+    @Test
+    public void testPost() {
+        mockGroupService.addGroup(anyObject());
+        expectLastCall();
+        replay(mockGroupService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = GroupsResourceTest.class
+                .getResourceAsStream("post-group.json");
+
+        Response response = wt.path("groups/of:0000000000000001")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/groups/of:0000000000000001/"));
+    }
+
+    /**
+     * Tests deleting a group.
+     */
+    @Test
+    public void testDelete() {
+        setupMockGroups();
+        mockGroupService.removeGroup(anyObject(), anyObject(), anyObject());
+        expectLastCall();
+        replay(mockGroupService);
+
+        WebTarget wt = target();
+
+        String location = "/groups/1/111";
+
+        Response deleteResponse = wt.path(location)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+        assertThat(deleteResponse.getStatus(),
+                is(HttpURLConnection.HTTP_NO_CONTENT));
+    }
+}
