diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java
index 06552073c223bc6447a1a6a37fec213355629348..35bda79dd451c0c0306c194d8d72b2bda43ba9e8 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java
@@ -50,7 +50,6 @@ import org.briarproject.bramble.api.transport.OutgoingKeys;
 import org.briarproject.bramble.api.transport.TransportKeys;
 import org.briarproject.bramble.test.BrambleMockTestCase;
 import org.briarproject.bramble.test.CaptureArgumentAction;
-import org.briarproject.bramble.test.TestUtils;
 import org.jmock.Expectations;
 import org.junit.Test;
 
@@ -64,14 +63,15 @@ import static java.util.Collections.singletonList;
 import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
 import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
 import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
-import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
 import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
 import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
 import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
+import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.bramble.test.TestUtils.getSecretKey;
 import static org.briarproject.bramble.test.TestUtils.getTransportId;
 import static org.junit.Assert.assertEquals;
@@ -106,13 +106,12 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
 
 	public DatabaseComponentImplTest() {
 		clientId = getClientId();
-		groupId = new GroupId(TestUtils.getRandomId());
-		byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
-		group = new Group(groupId, clientId, descriptor);
+		group = getGroup(clientId);
+		groupId = group.getId();
 		author = getAuthor();
 		localAuthor = getLocalAuthor();
-		messageId = new MessageId(TestUtils.getRandomId());
-		messageId1 = new MessageId(TestUtils.getRandomId());
+		messageId = new MessageId(getRandomId());
+		messageId1 = new MessageId(getRandomId());
 		long timestamp = System.currentTimeMillis();
 		size = 1234;
 		raw = new byte[size];
@@ -920,7 +919,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testGenerateOffer() throws Exception {
-		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId1 = new MessageId(getRandomId());
 		Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
@@ -951,7 +950,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testGenerateRequest() throws Exception {
-		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId1 = new MessageId(getRandomId());
 		Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
@@ -1139,9 +1138,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
 
 	@Test
 	public void testReceiveOffer() throws Exception {
-		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
-		MessageId messageId2 = new MessageId(TestUtils.getRandomId());
-		MessageId messageId3 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId1 = new MessageId(getRandomId());
+		MessageId messageId2 = new MessageId(getRandomId());
+		MessageId messageId3 = new MessageId(getRandomId());
 		context.checking(new Expectations() {{
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
@@ -1509,7 +1508,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
 	@SuppressWarnings("unchecked")
 	public void testMessageDependencies() throws Exception {
 		int shutdownHandle = 12345;
-		MessageId messageId2 = new MessageId(TestUtils.getRandomId());
+		MessageId messageId2 = new MessageId(getRandomId());
 		context.checking(new Expectations() {{
 			// open()
 			oneOf(database).open(null);
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java
index d1b898efe8b0cb247fc8f86303f1ed83472b318f..7b4618fbd93f07f11e172304af8dbb5fef61d333 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java
@@ -52,7 +52,6 @@ import static org.briarproject.bramble.api.db.Metadata.REMOVE;
 import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
 import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
 import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
-import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
 import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
@@ -60,6 +59,7 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
 import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -95,10 +95,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
 	private final KeySetId keySetId, keySetId1;
 
 	JdbcDatabaseTest() throws Exception {
-		groupId = new GroupId(getRandomId());
 		clientId = getClientId();
-		byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
-		group = new Group(groupId, clientId, descriptor);
+		group = getGroup(clientId);
+		groupId = group.getId();
 		author = getAuthor();
 		localAuthor = getLocalAuthor();
 		messageId = new MessageId(getRandomId());
@@ -1408,9 +1407,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
 		db.addMessage(txn, message, PENDING, true, contactId);
 
 		// Add a second group
-		GroupId groupId1 = new GroupId(getRandomId());
-		Group group1 = new Group(groupId1, clientId,
-				getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH));
+		Group group1 = getGroup(clientId);
+		GroupId groupId1 = group1.getId();
 		db.addGroup(txn, group1);
 
 		// Add a message to the second group
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java
index d122499bb1bed58036933dc5adea642c1f02f444..eced5fd82b9d284b042672ee2e3126c3a21181ef 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java
@@ -32,9 +32,9 @@ import java.util.Map;
 import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
 import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_VERSION;
 import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
-import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
 import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -51,7 +51,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 			context.mock(ContactGroupFactory.class);
 	private final Clock clock = context.mock(Clock.class);
 
-	private final Group localGroup = getGroup();
+	private final Group localGroup = getGroup(CLIENT_ID);
 	private final LocalAuthor localAuthor = getLocalAuthor();
 	private final BdfDictionary fooPropertiesDict = BdfDictionary.of(
 			new BdfEntry("fooKey1", "fooValue1"),
@@ -90,7 +90,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 		Contact contact1 = getContact(true);
 		Contact contact2 = getContact(true);
 		List<Contact> contacts = Arrays.asList(contact1, contact2);
-		Group contactGroup1 = getGroup(), contactGroup2 = getGroup();
+		Group contactGroup1 = getGroup(CLIENT_ID);
+		Group contactGroup2 = getGroup(CLIENT_ID);
 
 		context.checking(new Expectations() {{
 			oneOf(db).containsGroup(txn, localGroup.getId());
@@ -143,7 +144,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	public void testCreatesContactGroupWhenAddingContact() throws Exception {
 		Transaction txn = new Transaction(null, false);
 		Contact contact = getContact(true);
-		Group contactGroup = getGroup();
+		Group contactGroup = getGroup(CLIENT_ID);
 
 		context.checking(new Expectations() {{
 			// Create the group and share it with the contact
@@ -171,7 +172,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	public void testRemovesGroupWhenRemovingContact() throws Exception {
 		Transaction txn = new Transaction(null, false);
 		Contact contact = getContact(true);
-		Group contactGroup = getGroup();
+		Group contactGroup = getGroup(CLIENT_ID);
 
 		context.checking(new Expectations() {{
 			oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
@@ -306,7 +307,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	@Test
 	public void testStoresRemotePropertiesWithVersion0() throws Exception {
 		Contact contact = getContact(true);
-		Group contactGroup = getGroup();
+		Group contactGroup = getGroup(CLIENT_ID);
 		Transaction txn = new Transaction(null, false);
 		Map<TransportId, TransportProperties> properties =
 				new LinkedHashMap<>();
@@ -417,8 +418,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 		Contact contact3 = getContact(true);
 		List<Contact> contacts =
 				Arrays.asList(contact1, contact2, contact3);
-		Group contactGroup2 = getGroup();
-		Group contactGroup3 = getGroup();
+		Group contactGroup2 = getGroup(CLIENT_ID);
+		Group contactGroup3 = getGroup(CLIENT_ID);
 		Map<MessageId, BdfDictionary> messageMetadata3 =
 				new LinkedHashMap<>();
 		// A remote update for another transport should be ignored
@@ -514,7 +515,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	public void testMergingNewPropertiesCreatesUpdate() throws Exception {
 		Transaction txn = new Transaction(null, false);
 		Contact contact = getContact(true);
-		Group contactGroup = getGroup();
+		Group contactGroup = getGroup(CLIENT_ID);
 
 		context.checking(new Expectations() {{
 			oneOf(db).startTransaction(false);
@@ -549,7 +550,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 	public void testMergingUpdatedPropertiesCreatesUpdate() throws Exception {
 		Transaction txn = new Transaction(null, false);
 		Contact contact = getContact(true);
-		Group contactGroup = getGroup();
+		Group contactGroup = getGroup(CLIENT_ID);
 		BdfDictionary oldMetadata = BdfDictionary.of(
 				new BdfEntry("transportId", "foo"),
 				new BdfEntry("version", 1),
@@ -600,12 +601,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
 		t.mergeLocalProperties(new TransportId("foo"), fooProperties);
 	}
 
-	private Group getGroup() {
-		GroupId g = new GroupId(getRandomId());
-		byte[] descriptor = getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH);
-		return new Group(g, CLIENT_ID, descriptor);
-	}
-
 	private Contact getContact(boolean active) {
 		ContactId c = new ContactId(nextContactId++);
 		return new Contact(c, getAuthor(), localAuthor.getId(),
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java
index 5c197c46257f2cd5cec05d36ec86d4d50df7aefd..a3a23d4aef7a613b74f28f98ef72c6da1bd8ef46 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/sync/ValidationManagerImplTest.java
@@ -37,6 +37,7 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
 import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
 import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 
 public class ValidationManagerImplTest extends BrambleMockTestCase {
@@ -55,9 +56,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
 	private final MessageId messageId = new MessageId(getRandomId());
 	private final MessageId messageId1 = new MessageId(getRandomId());
 	private final MessageId messageId2 = new MessageId(getRandomId());
-	private final GroupId groupId = new GroupId(getRandomId());
-	private final byte[] descriptor = new byte[32];
-	private final Group group = new Group(groupId, clientId, descriptor);
+	private final Group group = getGroup(clientId);
+	private final GroupId groupId = group.getId();
 	private final long timestamp = System.currentTimeMillis();
 	private final byte[] raw = new byte[123];
 	private final Message message = new Message(messageId, groupId, timestamp,
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/ValidatorTestCase.java b/bramble-core/src/test/java/org/briarproject/bramble/test/ValidatorTestCase.java
index 7f38f7ad33711f991ca31eda9e6a5a4913df7add..799722344ba234014686b8549cd7c5bc7b6cb417 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/test/ValidatorTestCase.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/test/ValidatorTestCase.java
@@ -2,8 +2,6 @@ package org.briarproject.bramble.test;
 
 import org.briarproject.bramble.api.client.ClientHelper;
 import org.briarproject.bramble.api.data.MetadataEncoder;
-import org.briarproject.bramble.api.identity.AuthorFactory;
-import org.briarproject.bramble.api.sync.ClientId;
 import org.briarproject.bramble.api.sync.Group;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
@@ -11,6 +9,7 @@ import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.bramble.api.system.Clock;
 
 import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 
@@ -21,17 +20,14 @@ public abstract class ValidatorTestCase extends BrambleMockTestCase {
 	protected final MetadataEncoder metadataEncoder =
 			context.mock(MetadataEncoder.class);
 	protected final Clock clock = context.mock(Clock.class);
-	protected final AuthorFactory authorFactory =
-			context.mock(AuthorFactory.class);
 
+	protected final Group group = getGroup(getClientId());
+	protected final GroupId groupId = group.getId();
+	protected final byte[] descriptor = group.getDescriptor();
 	protected final MessageId messageId = new MessageId(getRandomId());
-	protected final GroupId groupId = new GroupId(getRandomId());
 	protected final long timestamp = 1234567890 * 1000L;
 	protected final byte[] raw = getRandomBytes(123);
 	protected final Message message =
 			new Message(messageId, groupId, timestamp, raw);
-	protected final ClientId clientId = getClientId();
-	protected final byte[] descriptor = getRandomBytes(123);
-	protected final Group group = new Group(groupId, clientId, descriptor);
 
 }
diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
index 41d1d3cd56959aa43ed28c1430416b3ee9fd31da..bbd905705a69572321662a4be9e79edbc69b9c80 100644
--- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
@@ -14,8 +14,6 @@ import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.IdentityManager;
 import org.briarproject.bramble.api.identity.LocalAuthor;
-import org.briarproject.bramble.api.sync.Group;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
 import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.briar.api.blog.Blog;
@@ -34,6 +32,7 @@ import static org.briarproject.bramble.api.identity.Author.Status.NONE;
 import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
 import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
 import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -867,9 +866,7 @@ public class BlogManagerImplTest extends BriarTestCase {
 	}
 
 	private Blog createBlog(LocalAuthor localAuthor, boolean rssFeed) {
-		GroupId groupId = new GroupId(getRandomId());
-		Group group = new Group(groupId, CLIENT_ID, getRandomBytes(42));
-		return new Blog(group, localAuthor, rssFeed);
+		return new Blog(getGroup(CLIENT_ID), localAuthor, rssFeed);
 	}
 
 	private BdfList authorToBdfList(Author a) {
diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java
index 8f5fe4aad6476f0aa1315ecf860ebd74c9bb900a..6ca21569d91dbfdb95887d895c1626992d463965 100644
--- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java
@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.data.MetadataEncoder;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.sync.Group;
 import org.briarproject.bramble.api.sync.GroupFactory;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
 import org.briarproject.bramble.api.sync.MessageFactory;
 import org.briarproject.bramble.api.sync.MessageId;
@@ -25,6 +24,7 @@ import java.io.IOException;
 import java.security.GeneralSecurityException;
 
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -64,9 +64,8 @@ public class BlogPostValidatorTest extends BriarTestCase {
 	private final String body = getRandomString(42);
 
 	public BlogPostValidatorTest() {
-		GroupId groupId = new GroupId(getRandomId());
-		descriptor = getRandomBytes(42);
-		group = new Group(groupId, CLIENT_ID, descriptor);
+		group = getGroup(CLIENT_ID);
+		descriptor = group.getDescriptor();
 		author = getAuthor();
 		authorList = BdfList.of(
 				author.getFormatVersion(),
diff --git a/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java
index 3ecc24c4ad430a1bc36f1dcc29439d4f7ea0a7db..0a11b0fea447cbb09a53982ae98db25d70c047ba 100644
--- a/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/client/MessageQueueManagerImplTest.java
@@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.briar.api.client.MessageQueueManager.QUEUE_STATE_KEY;
 import static org.briarproject.briar.api.client.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH;
 import static org.junit.Assert.assertEquals;
@@ -44,10 +45,9 @@ import static org.junit.Assert.fail;
 
 public class MessageQueueManagerImplTest extends BriarTestCase {
 
-	private final GroupId groupId = new GroupId(TestUtils.getRandomId());
 	private final ClientId clientId = getClientId();
-	private final byte[] descriptor = new byte[0];
-	private final Group group = new Group(groupId, clientId, descriptor);
+	private final Group group = getGroup(clientId);
+	private final GroupId groupId = group.getId();
 	private final long timestamp = System.currentTimeMillis();
 
 	@Test
diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
index d3e69e7ddf2c4b7b70aacdf12b5c43a3c30f3fb3..05a17fee5f776a51997a6a92cd93036b5d936108 100644
--- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
@@ -37,6 +37,7 @@ import javax.net.SocketFactory;
 
 import okhttp3.Dns;
 
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -60,12 +61,10 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
 	private final Clock clock = context.mock(Clock.class);
 	private final Dns noDnsLookups = context.mock(Dns.class);
 
-	private final GroupId localGroupId = new GroupId(getRandomId());
-	private final Group localGroup =
-			new Group(localGroupId, CLIENT_ID, getRandomBytes(42));
-	private final GroupId blogGroupId = new GroupId(getRandomId());
-	private final Group blogGroup =
-			new Group(blogGroupId, BlogManager.CLIENT_ID, getRandomBytes(42));
+	private final Group localGroup = getGroup(CLIENT_ID);
+	private final GroupId localGroupId = localGroup.getId();
+	private final Group blogGroup = getGroup(BlogManager.CLIENT_ID);
+	private final GroupId blogGroupId = blogGroup.getId();
 	private final LocalAuthor localAuthor = getLocalAuthor();
 	private final Blog blog = new Blog(blogGroup, localAuthor, true);
 	private final Feed feed =
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java
index 6617924ac12317fd5655bb27313ecf4c45c461ae..647502b131275c5cc7a7166a36023049ea62d74a 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroduceeManagerTest.java
@@ -19,7 +19,6 @@ import org.briarproject.bramble.api.identity.AuthorFactory;
 import org.briarproject.bramble.api.identity.AuthorId;
 import org.briarproject.bramble.api.identity.IdentityManager;
 import org.briarproject.bramble.api.properties.TransportPropertyManager;
-import org.briarproject.bramble.api.sync.ClientId;
 import org.briarproject.bramble.api.sync.Group;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
@@ -40,6 +39,7 @@ import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
 import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.bramble.test.TestUtils.getSecretKey;
@@ -79,6 +79,7 @@ import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_ACK;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_RESPONSE;
+import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID;
 import static org.hamcrest.Matchers.array;
 import static org.hamcrest.Matchers.samePropertyValuesAs;
 import static org.junit.Assert.assertFalse;
@@ -145,11 +146,8 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		introducee2 =
 				new Contact(contactId2, author2, localAuthorId, true, true);
 
-		ClientId clientId = IntroductionManagerImpl.CLIENT_ID;
-		localGroup1 = new Group(new GroupId(getRandomId()),
-				clientId, new byte[0]);
-		introductionGroup1 = new Group(new GroupId(getRandomId()),
-				clientId, new byte[0]);
+		localGroup1 = getGroup(CLIENT_ID);
+		introductionGroup1 = getGroup(CLIENT_ID);
 
 		sessionId = new SessionId(getRandomId());
 		localStateMessage = new Message(
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java
index d56cd5863752f5a8d7526e68cd8b7455fb48e1c5..558b26ec9b2fdb9452676dc54e4b86ff8bf2418c 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroducerManagerTest.java
@@ -12,9 +12,7 @@ import org.briarproject.bramble.api.db.DbException;
 import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.AuthorId;
-import org.briarproject.bramble.api.sync.ClientId;
 import org.briarproject.bramble.api.sync.Group;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
 import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.bramble.api.system.Clock;
@@ -27,6 +25,7 @@ import org.junit.Test;
 import java.security.SecureRandom;
 
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.briar.api.introduction.IntroducerProtocolState.AWAIT_RESPONSES;
@@ -50,6 +49,7 @@ import static org.briarproject.briar.api.introduction.IntroductionConstants.STAT
 import static org.briarproject.briar.api.introduction.IntroductionConstants.STORAGE_ID;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
+import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID;
 import static org.junit.Assert.assertFalse;
 
 public class IntroducerManagerTest extends BriarTestCase {
@@ -93,12 +93,9 @@ public class IntroducerManagerTest extends BriarTestCase {
 		introducee2 =
 				new Contact(contactId2, author2, localAuthorId2, true, true);
 
-		localGroup0 = new Group(new GroupId(getRandomId()),
-				getClientId(), new byte[0]);
-		introductionGroup1 = new Group(new GroupId(getRandomId()),
-				getClientId(), new byte[0]);
-		introductionGroup2 = new Group(new GroupId(getRandomId()),
-				getClientId(), new byte[0]);
+		localGroup0 = getGroup(CLIENT_ID);
+		introductionGroup1 = getGroup(CLIENT_ID);
+		introductionGroup2 = getGroup(CLIENT_ID);
 
 		context.assertIsSatisfied();
 	}
@@ -179,8 +176,4 @@ public class IntroducerManagerTest extends BriarTestCase {
 		assertFalse(txn.isCommitted());
 	}
 
-	private ClientId getClientId() {
-		return IntroductionManagerImpl.CLIENT_ID;
-	}
-
 }
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java
index fa480dc1a5049e69e75385d8d6b2d46a81eec2f2..e445910201364626e62d3d8b74b535d81ebd7d1c 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionManagerImplTest.java
@@ -13,9 +13,7 @@ import org.briarproject.bramble.api.db.DbException;
 import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.AuthorId;
-import org.briarproject.bramble.api.sync.ClientId;
 import org.briarproject.bramble.api.sync.Group;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
 import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.bramble.api.sync.MessageStatus;
@@ -33,7 +31,7 @@ import java.util.Map;
 
 import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
-import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID_1;
@@ -44,6 +42,7 @@ import static org.briarproject.briar.api.introduction.IntroductionConstants.SESS
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_REQUEST;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.TYPE_RESPONSE;
+import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID;
 import static org.junit.Assert.assertFalse;
 
 public class IntroductionManagerImplTest extends BriarTestCase {
@@ -79,11 +78,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 		introducee2 =
 				new Contact(contactId2, author2, localAuthorId2, true, true);
 
-		ClientId clientId = getClientId();
-		introductionGroup1 = new Group(new GroupId(getRandomId()),
-				clientId, new byte[0]);
-		introductionGroup2 = new Group(new GroupId(getRandomId()),
-				clientId, new byte[0]);
+		introductionGroup1 = getGroup(CLIENT_ID);
+		introductionGroup2 = getGroup(CLIENT_ID);
 
 		message1 = new Message(
 				new MessageId(getRandomId()),
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java
index bd786802f079c3585c006283d4f95723b1e8bf58..a2d481547c7c75e2e53c490f51ac4299bc10997f 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionValidatorTest.java
@@ -8,9 +8,7 @@ import org.briarproject.bramble.api.data.BdfList;
 import org.briarproject.bramble.api.data.MetadataEncoder;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.plugin.TransportId;
-import org.briarproject.bramble.api.sync.ClientId;
 import org.briarproject.bramble.api.sync.Group;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
 import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.bramble.api.system.Clock;
@@ -27,6 +25,8 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATUR
 import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
 import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
+import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -61,11 +61,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
 	private final Clock clock = new SystemClock();
 
 	public IntroductionValidatorTest() {
-		GroupId groupId = new GroupId(getRandomId());
-		ClientId clientId = new ClientId(getRandomString(5));
-		byte[] descriptor = getRandomBytes(12);
-		group = new Group(groupId, clientId, descriptor);
-
+		group = getGroup(getClientId());
 		MessageId messageId = new MessageId(getRandomId());
 		long timestamp = System.currentTimeMillis();
 		byte[] raw = getRandomBytes(123);
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java
index 56522918d7a218f39e53400552f8719406fe9f5e..1f922d70644fef119fa0b506dd25707ffa46b9d4 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/MessageSenderTest.java
@@ -11,7 +11,6 @@ import org.briarproject.bramble.api.db.DbException;
 import org.briarproject.bramble.api.db.Metadata;
 import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.sync.Group;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.system.Clock;
 import org.briarproject.briar.api.client.MessageQueueManager;
 import org.briarproject.briar.api.client.SessionId;
@@ -22,6 +21,7 @@ import org.junit.Test;
 
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getClientId;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID;
@@ -59,8 +59,7 @@ public class MessageSenderTest extends BriarTestCase {
 	@Test
 	public void testSendMessage() throws DbException, FormatException {
 		Transaction txn = new Transaction(null, false);
-		Group privateGroup = new Group(new GroupId(getRandomId()),
-				getClientId(), new byte[0]);
+		Group privateGroup = getGroup(getClientId());
 		SessionId sessionId = new SessionId(getRandomId());
 		byte[] mac = getRandomBytes(42);
 		byte[] sig = getRandomBytes(MAX_SIGNATURE_LENGTH);
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java
index 3cab16c48b7eef3106174de1e9c70bb02e31a49e..f7c630f655d37a903406ae069915c127e71f3c92 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java
@@ -25,6 +25,7 @@ import org.jmock.Expectations;
 
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
 import static org.briarproject.bramble.test.TestUtils.getAuthor;
+import static org.briarproject.bramble.test.TestUtils.getGroup;
 import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
 import static org.briarproject.bramble.test.TestUtils.getRandomId;
 import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -63,9 +64,8 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
 
 	protected final Transaction txn = new Transaction(null, false);
 	protected final GroupId contactGroupId = new GroupId(getRandomId());
-	protected final GroupId privateGroupId = new GroupId(getRandomId());
-	protected final Group privateGroupGroup =
-			new Group(privateGroupId, CLIENT_ID, getRandomBytes(123));
+	protected final Group privateGroupGroup = getGroup(CLIENT_ID);
+	protected final GroupId privateGroupId = privateGroupGroup.getId();
 	protected final Author author = getAuthor();
 	protected final PrivateGroup privateGroup =
 			new PrivateGroup(privateGroupGroup,
diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java
index e2a1ae4022fdbbfa63e59c0254f337acb545958e..c225d056dc7f3436c0ec6e2c5fbdbc11437e1b96 100644
--- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java
@@ -854,10 +854,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
 		Collection<Contact> contacts =
 				Arrays.asList(contact, contact2, contact3);
 
-		Group contactGroup2 = new Group(new GroupId(getRandomId()),
-				CLIENT_ID, getRandomBytes(5));
-		Group contactGroup3 = new Group(new GroupId(getRandomId()),
-				CLIENT_ID, getRandomBytes(5));
+		Group contactGroup2 = getGroup(CLIENT_ID);
+		Group contactGroup3 = getGroup(CLIENT_ID);
 
 		MessageId storageId2 = new MessageId(getRandomId());
 		MessageId storageId3 = new MessageId(getRandomId());
diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java
index d191fada2ca0e48474bddbc37d2aeda8c384bd36..46a9cb5e969119cce46a669750b7dc24bb03bec3 100644
--- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java
@@ -15,7 +15,6 @@ import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.IdentityManager;
 import org.briarproject.bramble.api.identity.LocalAuthor;
 import org.briarproject.bramble.api.sync.Group;
-import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
 import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.bramble.test.BrambleMockTestCase;
@@ -226,8 +225,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
 	private void expectPreShareShareable(Transaction txn, Contact contact,
 			Blog blog, Map<MessageId, BdfDictionary> sessions)
 			throws Exception {
-		Group contactGroup = new Group(new GroupId(getRandomId()), CLIENT_ID,
-				getRandomBytes(42));
+		Group contactGroup = getGroup(CLIENT_ID);
 		BdfDictionary sessionDict = new BdfDictionary();
 		Message message = new Message(new MessageId(getRandomId()),
 				contactGroup.getId(), 42L, getRandomBytes(1337));