diff --git a/cmd/group.go b/cmd/group.go
index 0595779059bae5297255cab14a74f573cd1b5247..7e9b8c63b1dcd5a034c168e9984d7f2020d8fd87 100644
--- a/cmd/group.go
+++ b/cmd/group.go
@@ -128,10 +128,8 @@ func initGroupManager(messenger *xxdk.E2e) (groupChat.GroupChat,
 	}
 
 	jww.INFO.Print("[GC] Creating new group manager.")
-	manager, err := groupChat.NewManager(messenger.GetCmix(),
-		messenger.GetE2E(), messenger.GetReceptionIdentity().ID,
-		messenger.GetRng(), messenger.GetStorage().GetE2EGroup(),
-		messenger.GetStorage().GetKV(), requestCb, &receiveProcessor{recChan})
+	manager, err := groupChat.NewManager(messenger, requestCb,
+		&receiveProcessor{recChan})
 	if err != nil {
 		jww.FATAL.Panicf("[GC] Failed to initialize group chat manager: %+v", err)
 	}
diff --git a/groupChat/e2eManager_test.go b/groupChat/e2eManager_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..cc66b2b7dfd6e0c6b4d489fd4a710974250ddd57
--- /dev/null
+++ b/groupChat/e2eManager_test.go
@@ -0,0 +1,191 @@
+package groupChat
+
+import (
+	"github.com/cloudflare/circl/dh/sidh"
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/cmix/message"
+	clientE2E "gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	sessionImport "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/elixxir/client/stoppable"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/e2e"
+	"gitlab.com/xx_network/primitives/id"
+	"sync"
+	"testing"
+	"time"
+)
+
+// testE2eManager is a test implementation of NetworkManager interface.
+type testE2eManager struct {
+	e2eMessages []testE2eMessage
+	partners    map[id.ID]partner.Manager
+	errSkip     int
+	sendErr     int
+	dhPubKey    *cyclic.Int
+	grp         *cyclic.Group
+	sync.RWMutex
+}
+
+type testE2eMessage struct {
+	Recipient *id.ID
+	Payload   []byte
+}
+
+func (tnm *testE2eManager) AddPartner(partnerID *id.ID, partnerPubKey,
+	myPrivKey *cyclic.Int, _ *sidh.PublicKey, _ *sidh.PrivateKey,
+	_, _ sessionImport.Params) (partner.Manager, error) {
+
+	testPartner := partner.NewTestManager(partnerID, partnerPubKey, myPrivKey, &testing.T{})
+	tnm.partners[*partnerID] = testPartner
+	return testPartner, nil
+}
+
+func (tnm *testE2eManager) GetPartner(partnerID *id.ID) (partner.Manager, error) {
+	if p, ok := tnm.partners[*partnerID]; ok {
+		return p, nil
+	}
+	return nil, errors.New("Unable to find partner")
+}
+
+func (tnm *testE2eManager) GetHistoricalDHPubkey() *cyclic.Int {
+	return tnm.dhPubKey
+}
+
+func (tnm *testE2eManager) GetHistoricalDHPrivkey() *cyclic.Int {
+	return tnm.dhPubKey
+}
+
+func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage {
+	tnm.RLock()
+	defer tnm.RUnlock()
+	return tnm.e2eMessages[i]
+}
+
+func (tnm *testE2eManager) SendE2E(_ catalog.MessageType, recipient *id.ID,
+	payload []byte, _ clientE2E.Params) ([]id.Round, e2e.MessageID, time.Time,
+	error) {
+	tnm.Lock()
+	defer tnm.Unlock()
+
+	tnm.errSkip++
+	if tnm.sendErr == 1 {
+		return nil, e2e.MessageID{}, time.Time{}, errors.New("SendE2E error")
+	} else if tnm.sendErr == 2 && tnm.errSkip%2 == 0 {
+		return nil, e2e.MessageID{}, time.Time{}, errors.New("SendE2E error")
+	}
+
+	tnm.e2eMessages = append(tnm.e2eMessages, testE2eMessage{
+		Recipient: recipient,
+		Payload:   payload,
+	})
+
+	return []id.Round{0, 1, 2, 3}, e2e.MessageID{}, time.Time{}, nil
+}
+
+func (*testE2eManager) RegisterListener(*id.ID, catalog.MessageType, receive.Listener) receive.ListenerID {
+	return receive.ListenerID{}
+}
+
+func (*testE2eManager) AddService(string, message.Processor) error {
+	return nil
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Unused & unimplemented methods of the test object ////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+
+func (*testE2eManager) GetDefaultHistoricalDHPubkey() *cyclic.Int {
+	panic("implement me")
+}
+
+func (*testE2eManager) GetDefaultHistoricalDHPrivkey() *cyclic.Int {
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) StartProcesses() (stoppable.Stoppable, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) RegisterFunc(name string, senderID *id.ID, messageType catalog.MessageType, newListener receive.ListenerFunc) receive.ListenerID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) RegisterChannel(name string, senderID *id.ID, messageType catalog.MessageType, newListener chan receive.Message) receive.ListenerID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) Unregister(listenerID receive.ListenerID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) UnregisterUserListeners(userID *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) DeletePartner(partnerId *id.ID) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) GetAllPartnerIDs() []*id.ID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) HasAuthenticatedChannel(partner *id.ID) bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) RemoveService(tag string) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) SendUnsafe(mt catalog.MessageType, recipient *id.ID, payload []byte, params clientE2E.Params) ([]id.Round, time.Time, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) EnableUnsafeReception() {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) GetGroup() *cyclic.Group {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) GetReceptionID() *id.ID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) FirstPartitionSize() uint {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) SecondPartitionSize() uint {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) PartitionSize(payloadIndex uint) uint {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testE2eManager) PayloadSize() uint {
+	//TODO implement me
+	panic("implement me")
+}
diff --git a/groupChat/interface.go b/groupChat/interface.go
index 9604b5d8b39726460f374d3531715be7697510f7..0355c90943797cb7ab98d7e02e648ba946f1692b 100644
--- a/groupChat/interface.go
+++ b/groupChat/interface.go
@@ -20,9 +20,23 @@
 package groupChat
 
 import (
+	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/elixxir/client/cmix/message"
+	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	sessionImport "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/e2e/receive"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/client/xxdk"
+	"gitlab.com/elixxir/crypto/cyclic"
+	crypto "gitlab.com/elixxir/crypto/e2e"
+	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/id/ephemeral"
 	"time"
 )
 
@@ -81,3 +95,45 @@ type RequestCallback func(g gs.Group)
 
 // ReceiveCallback is called when a GroupChat message is received.
 type ReceiveCallback func(msg MessageReceive)
+
+////////////////////////////////////////////////////////////////////////////////////
+// Sub-interfaces from other packages //////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+
+// groupE2e is a sub-interface mocking the xxdk.E2e object.
+// This contains methods specific for this package.
+type groupE2e interface {
+	GetCmix() cmix.Client
+	GetE2E() e2e.Handler
+	GetReceptionIdentity() xxdk.ReceptionIdentity
+	GetRng() *fastRNG.StreamGenerator
+	GetStorage() storage.Session
+}
+
+// groupCmix is a subset of the cmix.Client interface containing only the
+// methods needed by GroupChat
+type groupCmix interface {
+	SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (
+		id.Round, []ephemeral.Id, error)
+	AddService(
+		clientID *id.ID, newService message.Service, response message.Processor)
+	DeleteService(
+		clientID *id.ID, toDelete message.Service, processor message.Processor)
+	GetMaxMessageLength() int
+}
+
+// groupE2eHandler is a subset of the e2e.Handler interface containing only the methods
+// needed by GroupChat
+type groupE2eHandler interface {
+	SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte,
+		params e2e.Params) ([]id.Round, crypto.MessageID, time.Time, error)
+	RegisterListener(senderID *id.ID, messageType catalog.MessageType,
+		newListener receive.Listener) receive.ListenerID
+	AddService(tag string, processor message.Processor) error
+	AddPartner(partnerID *id.ID, partnerPubKey, myPrivKey *cyclic.Int,
+		partnerSIDHPubKey *sidh.PublicKey, mySIDHPrivKey *sidh.PrivateKey,
+		sendParams, receiveParams sessionImport.Params) (partner.Manager, error)
+	GetPartner(partnerID *id.ID) (partner.Manager, error)
+	GetHistoricalDHPubkey() *cyclic.Int
+	GetHistoricalDHPrivkey() *cyclic.Int
+}
diff --git a/groupChat/makeGroup.go b/groupChat/makeGroup.go
index 900221e423db1fca1249ac61d6f6e30ed313c8b1..b7db0a1033a848009ac63e58f0357920382136fa 100644
--- a/groupChat/makeGroup.go
+++ b/groupChat/makeGroup.go
@@ -66,7 +66,7 @@ func (m *manager) MakeGroup(membership []*id.ID, name, msg []byte) (gs.Group,
 	}
 
 	// Generate ID and key preimages
-	idPreimage, keyPreimage, err := getPreimages(m.rng)
+	idPreimage, keyPreimage, err := getPreimages(m.getRng())
 	if err != nil {
 		return gs.Group{}, nil, NotSent, err
 	}
@@ -114,7 +114,7 @@ func (m *manager) buildMembership(members []*id.ID) (group.Membership,
 	contacts := make([]contact.Contact, len(members))
 	var err error
 	for i, uid := range members {
-		partner, err := m.e2e.GetPartner(uid)
+		partner, err := m.getE2eHandler().GetPartner(uid)
 		if err != nil {
 			return nil, nil, errors.Errorf(getPartnerErr, uid, err)
 		}
@@ -127,7 +127,7 @@ func (m *manager) buildMembership(members []*id.ID) (group.Membership,
 		dkl.Add(partner.MyRootPrivateKey(), group.Member{
 			ID:    partner.PartnerId(),
 			DhKey: partner.PartnerRootPublicKey(),
-		}, m.grp)
+		}, m.getE2eGroup())
 	}
 
 	// Create new Membership from contact list and client's own contact.
diff --git a/groupChat/makeGroup_test.go b/groupChat/makeGroup_test.go
index b08b9766a3f8397bb37e3c8f896f05c236849bc0..737ca52cae289725ccd264abe90020e5b0c64ea2 100644
--- a/groupChat/makeGroup_test.go
+++ b/groupChat/makeGroup_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"fmt"
 	"github.com/cloudflare/circl/dh/sidh"
-	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	sessionImport "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/crypto/fastRNG"
@@ -132,8 +132,7 @@ func Test_manager_MakeGroup_AddGroupError(t *testing.T) {
 
 // Unit test of manager.buildMembership.
 func Test_manager_buildMembership(t *testing.T) {
-	prng := rand.New(rand.NewSource(42))
-	m, _ := newTestManager(prng, t)
+	m, _ := newTestManager(t)
 	memberIDs, expected, expectedDKL := addPartners(m, t)
 
 	membership, dkl, err := m.buildMembership(memberIDs)
@@ -155,7 +154,7 @@ func Test_manager_buildMembership(t *testing.T) {
 // Error path: an error is returned when the number of members in the membership
 // list is too few.
 func Test_manager_buildMembership_MinParticipantsError(t *testing.T) {
-	m, _ := newTestManager(rand.New(rand.NewSource(42)), t)
+	m, _ := newTestManager(t)
 	memberIDs := make([]*id.ID, group.MinParticipants-1)
 	expectedErr := fmt.Sprintf(
 		minMembersErr, len(memberIDs), group.MinParticipants)
@@ -170,7 +169,7 @@ func Test_manager_buildMembership_MinParticipantsError(t *testing.T) {
 // Error path: an error is returned when the number of members in the membership
 // list is too many.
 func Test_manager_buildMembership_MaxParticipantsError(t *testing.T) {
-	m, _ := newTestManager(rand.New(rand.NewSource(42)), t)
+	m, _ := newTestManager(t)
 	memberIDs := make([]*id.ID, group.MaxParticipants+1)
 	expectedErr := fmt.Sprintf(
 		maxMembersErr, len(memberIDs), group.MaxParticipants)
@@ -184,8 +183,7 @@ func Test_manager_buildMembership_MaxParticipantsError(t *testing.T) {
 
 // Error path: error returned when a partner cannot be found
 func Test_manager_buildMembership_GetPartnerContactError(t *testing.T) {
-	prng := rand.New(rand.NewSource(42))
-	m, _ := newTestManager(prng, t)
+	m, _ := newTestManager(t)
 	memberIDs, _, _ := addPartners(m, t)
 	expectedErr := strings.SplitN(getPartnerErr, "%", 2)[0]
 
@@ -201,8 +199,7 @@ func Test_manager_buildMembership_GetPartnerContactError(t *testing.T) {
 
 // Error path: error returned when a member ID appears twice on the list.
 func Test_manager_buildMembership_DuplicateContactError(t *testing.T) {
-	prng := rand.New(rand.NewSource(42))
-	m, _ := newTestManager(prng, t)
+	m, _ := newTestManager(t)
 	memberIDs, _, _ := addPartners(m, t)
 	expectedErr := strings.SplitN(makeMembershipErr, "%", 2)[0]
 
@@ -290,7 +287,7 @@ func addPartners(m *manager, t *testing.T) ([]*id.ID, group.Membership,
 	for i := range memberIDs {
 		// Build member data
 		uid := id.NewIdFromUInt(uint64(i), id.User, t)
-		dhKey := m.grp.NewInt(int64(i + 42))
+		dhKey := m.getE2eGroup().NewInt(int64(i + 42))
 
 		myVariant := sidh.KeyVariantSidhA
 		prng := rand.New(rand.NewSource(int64(i + 42)))
@@ -309,13 +306,13 @@ func addPartners(m *manager, t *testing.T) ([]*id.ID, group.Membership,
 		memberIDs[i] = uid
 		members = append(members, group.Member{ID: uid, DhKey: dhKey})
 		dkl.Add(dhKey, group.Member{ID: uid, DhKey: dhKey},
-			m.grp)
+			m.getE2eGroup())
 
 		// Add partner
-		_, err := m.e2e.AddPartner(uid, dhKey, dhKey,
+		_, err := m.getE2eHandler().AddPartner(uid, dhKey, dhKey,
 			theirSIDHPubKey, mySIDHPrivKey,
-			session.GetDefaultParams(),
-			session.GetDefaultParams())
+			sessionImport.GetDefaultParams(),
+			sessionImport.GetDefaultParams())
 		if err != nil {
 			t.Errorf("Failed to add partner %d: %+v", i, err)
 		}
diff --git a/groupChat/manager.go b/groupChat/manager.go
index f040e6498a6c8bcfc40634e7e0f7cb023cf29ba3..37ef25a0a621d598d7eedc4556bcbb85971a8fb4 100644
--- a/groupChat/manager.go
+++ b/groupChat/manager.go
@@ -8,27 +8,16 @@
 package groupChat
 
 import (
-	"sync"
-	"time"
-
-	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/catalog"
-	"gitlab.com/elixxir/client/cmix"
-	"gitlab.com/elixxir/client/cmix/message"
-	"gitlab.com/elixxir/client/e2e"
-	"gitlab.com/elixxir/client/e2e/ratchet/partner"
-	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
-	"gitlab.com/elixxir/client/e2e/receive"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
-	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/client/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
-	crypto "gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/xx_network/primitives/id"
-	"gitlab.com/xx_network/primitives/id/ephemeral"
+	"sync"
 )
 
 // Error messages.
@@ -46,34 +35,6 @@ const (
 
 const defaultServiceTag = "default"
 
-// GroupCmix is a subset of the cmix.Client interface containing only the
-// methods needed by GroupChat
-type GroupCmix interface {
-	SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (
-		id.Round, []ephemeral.Id, error)
-	AddService(
-		clientID *id.ID, newService message.Service, response message.Processor)
-	DeleteService(
-		clientID *id.ID, toDelete message.Service, processor message.Processor)
-	GetMaxMessageLength() int
-}
-
-// GroupE2e is a subset of the e2e.Handler interface containing only the methods
-// needed by GroupChat
-type GroupE2e interface {
-	SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte,
-		params e2e.Params) ([]id.Round, crypto.MessageID, time.Time, error)
-	RegisterListener(senderID *id.ID, messageType catalog.MessageType,
-		newListener receive.Listener) receive.ListenerID
-	AddService(tag string, processor message.Processor) error
-	AddPartner(partnerID *id.ID, partnerPubKey, myPrivKey *cyclic.Int,
-		partnerSIDHPubKey *sidh.PublicKey, mySIDHPrivKey *sidh.PrivateKey,
-		sendParams, receiveParams session.Params) (partner.Manager, error)
-	GetPartner(partnerID *id.ID) (partner.Manager, error)
-	GetHistoricalDHPubkey() *cyclic.Int
-	GetHistoricalDHPrivkey() *cyclic.Int
-}
-
 // manager handles the list of groups a user is a part of.
 type manager struct {
 	// Group storage
@@ -86,21 +47,23 @@ type manager struct {
 	// Callback that is called when a new group request is received
 	requestFunc RequestCallback
 
-	receptionId *id.ID
-	net         GroupCmix
-	e2e         GroupE2e
-	grp         *cyclic.Group
-	rng         *fastRNG.StreamGenerator
+	messenger groupE2e
 }
 
 // NewManager creates a new group chat manager
-func NewManager(services GroupCmix, e2e GroupE2e, receptionId *id.ID,
-	rng *fastRNG.StreamGenerator, grp *cyclic.Group, kv *versioned.KV,
+func NewManager(messenger groupE2e,
 	requestFunc RequestCallback, receiveFunc Processor) (GroupChat, error) {
 
+	// Initialize a member object
+	handler := messenger.GetE2E()
+	member := group.Member{
+		ID:    messenger.GetReceptionIdentity().ID,
+		DhKey: handler.GetHistoricalDHPubkey(),
+	}
+
 	// Load the group chat storage or create one if one does not exist
-	gStore, err := gs.NewOrLoadStore(
-		kv, group.Member{ID: receptionId, DhKey: e2e.GetHistoricalDHPubkey()})
+	kv := messenger.GetStorage().GetKV()
+	gStore, err := gs.NewOrLoadStore(kv, member)
 	if err != nil {
 		return nil, errors.Errorf(newGroupStoreErr, err)
 	}
@@ -110,19 +73,15 @@ func NewManager(services GroupCmix, e2e GroupE2e, receptionId *id.ID,
 		gs:          gStore,
 		services:    make(map[string]Processor),
 		requestFunc: requestFunc,
-		receptionId: receptionId,
-		net:         services,
-		e2e:         e2e,
-		grp:         grp,
-		rng:         rng,
+		messenger:   messenger,
 	}
 
 	// Register listener for incoming e2e group chat requests
-	e2e.RegisterListener(
+	handler.RegisterListener(
 		&id.ZeroUser, catalog.GroupCreationRequest, &requestListener{m})
 
 	// Register notifications listener for incoming e2e group chat requests
-	err = e2e.AddService(catalog.GroupRq, nil)
+	err = handler.AddService(catalog.GroupRq, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -179,3 +138,27 @@ func (m *manager) GetGroup(groupID *id.ID) (gs.Group, bool) {
 func (m *manager) NumGroups() int {
 	return m.gs.Len()
 }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Internal getters /////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+func (m *manager) getCMix() groupCmix {
+	return m.messenger.GetCmix()
+}
+
+func (m *manager) getE2eHandler() groupE2eHandler {
+	return m.messenger.GetE2E()
+}
+
+func (m *manager) getReceptionIdentity() xxdk.ReceptionIdentity {
+	return m.messenger.GetReceptionIdentity()
+}
+
+func (m *manager) getRng() *fastRNG.StreamGenerator {
+	return m.messenger.GetRng()
+}
+
+func (m *manager) getE2eGroup() *cyclic.Group {
+	return m.messenger.GetStorage().GetE2EGroup()
+}
diff --git a/groupChat/manager_test.go b/groupChat/manager_test.go
index de32491e49f2b7555783abc49d26d131c81a877e..07009a543eb81165ffb2e6c6f4397bf1b8ce4712 100644
--- a/groupChat/manager_test.go
+++ b/groupChat/manager_test.go
@@ -11,7 +11,7 @@ import (
 	"gitlab.com/elixxir/client/cmix"
 	"gitlab.com/elixxir/client/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/cmix/rounds"
-	"gitlab.com/elixxir/client/e2e"
+	e2eImport "gitlab.com/elixxir/client/e2e"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/group"
@@ -28,11 +28,11 @@ import (
 // Tests that manager adheres to the GroupChat interface.
 var _ GroupChat = (*manager)(nil)
 
-// Tests that GroupCmix adheres to the cmix.Client interface.
-var _ GroupCmix = (cmix.Client)(nil)
+// Tests that groupCmix adheres to the cmix.Client interface.
+var _ groupCmix = (cmix.Client)(nil)
 
-// Tests that GroupE2e adheres to the e2e.Handler interface.
-var _ GroupE2e = (e2e.Handler)(nil)
+// Tests that groupE2eHandler adheres to the e2e.Handler interface.
+var _ groupE2eHandler = (e2eImport.Handler)(nil)
 
 type mockProcessor struct{ receiveChan chan MessageReceive }
 
@@ -44,20 +44,23 @@ func (m mockProcessor) String() string { return "mockProcessor" }
 
 // Unit test of NewManager.
 func TestNewManager(t *testing.T) {
-	kv := versioned.NewKV(ekv.MakeMemstore())
-	user := group.Member{
-		ID:    id.NewIdFromString("userID", id.User, t),
-		DhKey: randCycInt(rand.New(rand.NewSource(42))),
-	}
+
 	requestChan := make(chan gs.Group)
 	requestFunc := func(g gs.Group) { requestChan <- g }
 	receiveChan := make(chan MessageReceive)
-	gcInt, err := NewManager(nil, newTestE2eManager(user.DhKey), user.ID, nil,
-		nil, kv, requestFunc, mockProcessor{receiveChan})
+	mockMess := newMockMessenger(t, nil)
+	gcInt, err := NewManager(mockMess, requestFunc,
+		mockProcessor{receiveChan})
 	if err != nil {
 		t.Errorf("NewManager returned an error: %+v", err)
 	}
 
+	dhKeyPub := mockMess.GetE2E().GetHistoricalDHPubkey()
+	user := group.Member{
+		ID:    mockMess.GetReceptionIdentity().ID,
+		DhKey: dhKeyPub,
+	}
+
 	m := gcInt.(*manager)
 
 	if !m.gs.GetUser().Equal(user) {
@@ -85,7 +88,7 @@ func TestNewManager_LoadStorage(t *testing.T) {
 	kv := versioned.NewKV(ekv.MakeMemstore())
 	user := group.Member{
 		ID:    id.NewIdFromString("userID", id.User, t),
-		DhKey: randCycInt(rand.New(rand.NewSource(42))),
+		DhKey: randCycInt(prng),
 	}
 
 	gStore, err := gs.NewStore(kv, user)
@@ -93,25 +96,28 @@ func TestNewManager_LoadStorage(t *testing.T) {
 		t.Errorf("Failed to create new group storage: %+v", err)
 	}
 
+	expectedGroups := make([]gs.Group, 0)
 	for i := 0; i < 10; i++ {
-		err := gStore.Add(
-			newTestGroup(getGroup(), getGroup().NewInt(42), prng, t))
+		grp := newTestGroup(getGroup(), getGroup().NewInt(42), prng, t)
+		err := gStore.Add(grp)
 		if err != nil {
 			t.Errorf("Failed to add group %d: %+v", i, err)
 		}
+		expectedGroups = append(expectedGroups, grp)
 	}
 
-	gcInt, err := NewManager(newTestNetworkManager(0, t),
-		newTestE2eManager(user.DhKey), user.ID, nil, nil, kv, nil, nil)
+	mockMess := newMockMessenger(t, kv)
+	gcInt, err := NewManager(mockMess, nil, nil)
 	if err != nil {
 		t.Errorf("NewManager returned an error: %+v", err)
 	}
 
 	m := gcInt.(*manager)
 
-	if !reflect.DeepEqual(gStore, m.gs) {
-		t.Errorf("NewManager failed to load the expected storage."+
-			"\nexpected: %+v\nreceived: %+v", gStore, m.gs)
+	for _, grp := range expectedGroups {
+		if _, exists := m.gs.Get(grp.ID); !exists {
+			t.Errorf("NewManager failed to load the expected storage.")
+		}
 	}
 }
 
@@ -138,7 +144,8 @@ func TestNewManager_LoadError(t *testing.T) {
 
 	expectedErr := strings.SplitN(newGroupStoreErr, "%", 2)[0]
 
-	_, err = NewManager(nil, newTestE2eManager(user.DhKey), user.ID, nil, nil, kv, nil, nil)
+	mockMess := newMockMessenger(t, kv)
+	_, err = NewManager(mockMess, nil, nil)
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("NewManager did not return the expected error."+
 			"\nexpected: %s\nreceived: %+v", expectedErr, err)
@@ -294,7 +301,7 @@ func TestNewManager_LoadError(t *testing.T) {
 func Test_manager_JoinGroup(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 	m, _ := newTestManagerWithStore(prng, 10, 0, nil, t)
-	g := newTestGroup(m.grp, m.e2e.GetHistoricalDHPubkey(), prng, t)
+	g := newTestGroup(m.getE2eGroup(), m.getE2eHandler().GetHistoricalDHPubkey(), prng, t)
 
 	err := m.JoinGroup(g)
 	if err != nil {
diff --git a/groupChat/messenger_test.go b/groupChat/messenger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..91894745298dff434b9459d2dffcbae870fb29b0
--- /dev/null
+++ b/groupChat/messenger_test.go
@@ -0,0 +1,95 @@
+package groupChat
+
+import (
+	"gitlab.com/elixxir/client/cmix"
+	clientE2E "gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/client/xxdk"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/crypto/csprng"
+	"gitlab.com/xx_network/primitives/id"
+	"math/rand"
+	"testing"
+)
+
+// mockMessenger implementation for groupE2e interface
+type mockMessenger struct {
+	receptionId *id.ID
+	net         cmix.Client
+	e2e         clientE2E.Handler
+	e2eGroup    *cyclic.Group
+	rng         *fastRNG.StreamGenerator
+	storage     storage.Session
+}
+
+func newMockMessenger(t testing.TB, kv *versioned.KV) groupE2e {
+	receptionId := id.NewIdFromString("test", id.User, t)
+	mockCmix := newTestNetworkManager(0)
+	prng := rand.New(rand.NewSource(42))
+	e2eHandler := newTestE2eManager(randCycInt(prng), t)
+	grp := getGroup()
+	rng := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG)
+	mockSession := newMockSesion(kv)
+
+	return mockMessenger{
+		receptionId: receptionId,
+		net:         mockCmix,
+		e2e:         e2eHandler,
+		e2eGroup:    grp,
+		rng:         rng,
+		storage:     mockSession,
+	}
+}
+
+func newMockMessengerWithStore(t testing.TB, sendErr int) groupE2e {
+	receptionId := id.NewIdFromString("test", id.User, t)
+	mockCmix := newTestNetworkManager(sendErr)
+	prng := rand.New(rand.NewSource(42))
+	grp := getGroup()
+	rng := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG)
+	mockSession := newMockSesion(nil)
+
+	return mockMessenger{
+		receptionId: receptionId,
+		net:         mockCmix,
+		e2e: &testE2eManager{
+			e2eMessages: []testE2eMessage{},
+			sendErr:     sendErr,
+			grp:         getGroup(),
+			dhPubKey:    randCycInt(prng),
+			partners:    make(map[id.ID]partner.Manager),
+		},
+		e2eGroup: grp,
+		rng:      rng,
+		storage:  mockSession,
+	}
+}
+
+func (m mockMessenger) GetCmix() cmix.Client {
+	return m.net
+}
+
+func (m mockMessenger) GetE2E() clientE2E.Handler {
+	return m.e2e
+}
+
+func (m mockMessenger) GetReceptionIdentity() xxdk.ReceptionIdentity {
+	keyData, _ := m.e2e.GetHistoricalDHPrivkey().MarshalJSON()
+	groupData, _ := getGroup().MarshalJSON()
+	return xxdk.ReceptionIdentity{
+		ID:           m.receptionId,
+		DHKeyPrivate: keyData,
+		E2eGrp:       groupData,
+	}
+}
+
+func (m mockMessenger) GetRng() *fastRNG.StreamGenerator {
+	return m.rng
+}
+
+func (m mockMessenger) GetStorage() storage.Session {
+	return m.storage
+}
diff --git a/groupChat/networkManager_test.go b/groupChat/networkManager_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a6df5a6427d976a21a652d89db81e8941348f34e
--- /dev/null
+++ b/groupChat/networkManager_test.go
@@ -0,0 +1,216 @@
+package groupChat
+
+import (
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/elixxir/client/cmix/gateway"
+	"gitlab.com/elixxir/client/cmix/identity"
+	"gitlab.com/elixxir/client/cmix/message"
+	"gitlab.com/elixxir/client/cmix/rounds"
+	"gitlab.com/elixxir/client/stoppable"
+	"gitlab.com/elixxir/comms/network"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/primitives/format"
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/id/ephemeral"
+	"sync"
+	"time"
+)
+
+// testNetworkManager is a test implementation of NetworkManager interface.
+type testNetworkManager struct {
+	receptionMessages [][]format.Message
+	sendMessages      [][]cmix.TargetedCmixMessage
+	errSkip           int
+	sendErr           int
+	grp               *cyclic.Group
+	sync.RWMutex
+}
+
+func newTestNetworkManager(sendErr int) cmix.Client {
+	return &testNetworkManager{
+		receptionMessages: [][]format.Message{},
+		sendMessages:      [][]cmix.TargetedCmixMessage{},
+		grp:               getGroup(),
+		sendErr:           sendErr,
+	}
+}
+
+func (tnm *testNetworkManager) SendMany(messages []cmix.TargetedCmixMessage, _ cmix.CMIXParams) (id.Round, []ephemeral.Id, error) {
+	if tnm.sendErr == 1 {
+		return 0, nil, errors.New("SendManyCMIX error")
+	}
+
+	tnm.Lock()
+	defer tnm.Unlock()
+
+	tnm.sendMessages = append(tnm.sendMessages, messages)
+
+	var receiveMessages []format.Message
+	for _, msg := range messages {
+		receiveMsg := format.NewMessage(tnm.grp.GetP().ByteLen())
+		receiveMsg.SetMac(msg.Mac)
+		receiveMsg.SetContents(msg.Payload)
+		receiveMsg.SetKeyFP(msg.Fingerprint)
+		receiveMessages = append(receiveMessages, receiveMsg)
+	}
+	tnm.receptionMessages = append(tnm.receptionMessages, receiveMessages)
+	return 0, nil, nil
+}
+
+func (*testNetworkManager) AddService(*id.ID, message.Service, message.Processor)    {}
+func (*testNetworkManager) DeleteService(*id.ID, message.Service, message.Processor) {}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Unused & unimplemented methods of the test object ////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+
+func (tnm *testNetworkManager) Follow(report cmix.ClientErrorReport) (stoppable.Stoppable, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) Send(recipient *id.ID, fingerprint format.Fingerprint, service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) AddIdentity(id *id.ID, validUntil time.Time, persistent bool) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) RemoveIdentity(id *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetIdentity(get *id.ID) (identity.TrackedID, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) AddFingerprint(identity *id.ID, fingerprint format.Fingerprint, mp message.Processor) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) DeleteClientFingerprints(identity *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) DeleteClientService(clientID *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) TrackServices(tracker message.ServicesTracker) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) CheckInProgressMessages() {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) IsHealthy() bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) WasHealthy() bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) AddHealthCallback(f func(bool)) uint64 {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) RemoveHealthCallback(u uint64) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) HasNode(nid *id.ID) bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) NumRegisteredNodes() int {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) TriggerNodeRegistration(nid *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetRoundResults(timeout time.Duration, roundCallback cmix.RoundEventCallback, roundList ...id.Round) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) LookupHistoricalRound(rid id.Round, callback rounds.RoundResultCallback) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) SendToAny(sendFunc func(host *connect.Host) (interface{}, error), stop *stoppable.Single) (interface{}, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) SendToPreferred(targets []*id.ID, sendFunc gateway.SendToPreferredFunc, stop *stoppable.Single, timeout time.Duration) (interface{}, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) SetGatewayFilter(f gateway.Filter) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetHostParams() connect.HostParams {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetAddressSpace() uint8 {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) RegisterAddressSpaceNotification(tag string) (chan uint8, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) UnregisterAddressSpaceNotification(tag string) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetInstance() *network.Instance {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetVerboseRounds() string {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (tnm *testNetworkManager) GetMaxMessageLength() int {
+	return format.NewMessage(tnm.grp.GetP().ByteLen()).ContentsSize()
+}
diff --git a/groupChat/receive.go b/groupChat/receive.go
index 63e6f91c0c904351d2c8590d29ebb7aa9a6d98d8..aecbfad2ee37d9242a70e3e5f1a8d21773854340 100644
--- a/groupChat/receive.go
+++ b/groupChat/receive.go
@@ -86,9 +86,11 @@ func (p *receptionProcessor) Process(message format.Message,
 
 func (p *receptionProcessor) String() string {
 	if p.p == nil {
-		return fmt.Sprintf("GroupChatReception(%s)", p.m.receptionId)
+		return fmt.Sprintf("GroupChatReception(%s)",
+			p.m.getReceptionIdentity().ID)
 	}
-	return fmt.Sprintf("GroupChatReception(%s)-%s", p.m.receptionId, p.p)
+	return fmt.Sprintf("GroupChatReception(%s)-%s",
+		p.m.getReceptionIdentity().ID, p.p)
 }
 
 // decryptMessage decrypts the group message payload and returns its message ID,
diff --git a/groupChat/receiveRequest.go b/groupChat/receiveRequest.go
index d76744315edf613ca05cb5efbdfba889e7cfadd9..104a326f1101f966510daea00db75a0c613efa67 100644
--- a/groupChat/receiveRequest.go
+++ b/groupChat/receiveRequest.go
@@ -78,7 +78,7 @@ func (m *manager) readRequest(msg receive.Message) (gs.Group, error) {
 	}
 
 	// get the relationship with the group leader
-	partner, err := m.e2e.GetPartner(membership[0].ID)
+	partner, err := m.getE2eHandler().GetPartner(membership[0].ID)
 	if err != nil {
 		return gs.Group{}, errors.Errorf(getPrivKeyErr, err)
 	}
@@ -89,7 +89,7 @@ func (m *manager) readRequest(msg receive.Message) (gs.Group, error) {
 
 	// Generate the DH keys with each group member
 	privKey := partner.MyRootPrivateKey()
-	dkl := gs.GenerateDhKeyList(m.receptionId, privKey, membership, m.grp)
+	dkl := gs.GenerateDhKeyList(m.getReceptionIdentity().ID, privKey, membership, m.getE2eGroup())
 
 	// Restore the original public key for the leader so that the membership
 	// digest generated later is correct
diff --git a/groupChat/receiveRequest_test.go b/groupChat/receiveRequest_test.go
index 04ba441bf308d2e68ab20985630b36c2a65a4b00..d1283b8955f319e526322882d5b609e96282c3c2 100644
--- a/groupChat/receiveRequest_test.go
+++ b/groupChat/receiveRequest_test.go
@@ -11,7 +11,7 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/catalog"
-	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	sessionImport "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/e2e/receive"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	util "gitlab.com/elixxir/client/storage/utility"
@@ -28,9 +28,9 @@ func TestRequestListener_Hear(t *testing.T) {
 	requestChan := make(chan gs.Group)
 	requestFunc := func(g gs.Group) { requestChan <- g }
 	m, _ := newTestManagerWithStore(prng, 10, 0, requestFunc, t)
-	g := newTestGroupWithUser(m.grp,
-		m.receptionId, m.e2e.GetHistoricalDHPubkey(),
-		m.e2e.GetHistoricalDHPrivkey(), prng, t)
+	g := newTestGroupWithUser(m.getE2eGroup(),
+		m.getReceptionIdentity().ID, m.getE2eHandler().GetHistoricalDHPubkey(),
+		m.getE2eHandler().GetHistoricalDHPrivkey(), prng, t)
 
 	requestMarshaled, err := proto.Marshal(&Request{
 		Name:        g.Name,
@@ -63,13 +63,13 @@ func TestRequestListener_Hear(t *testing.T) {
 	_ = theirSIDHPrivKey.Generate(prng)
 	theirSIDHPrivKey.GeneratePublicKey(theirSIDHPubKey)
 
-	_, _ = m.e2e.AddPartner(
+	_, _ = m.getE2eHandler().AddPartner(
 		g.Members[0].ID,
 		g.Members[0].DhKey,
-		m.e2e.GetHistoricalDHPrivkey(),
+		m.getE2eHandler().GetHistoricalDHPrivkey(),
 		theirSIDHPubKey, mySIDHPrivKey,
-		session.GetDefaultParams(),
-		session.GetDefaultParams(),
+		sessionImport.GetDefaultParams(),
+		sessionImport.GetDefaultParams(),
 	)
 
 	go listener.Hear(msg)
@@ -148,7 +148,7 @@ func TestRequestListener_Hear_BadMessageType(t *testing.T) {
 // Unit test of readRequest.
 func Test_manager_readRequest(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
-	m, g := newTestManager(prng, t)
+	m, g := newTestManager(t)
 
 	myVariant := sidh.KeyVariantSidhA
 	mySIDHPrivKey := util.NewSIDHPrivateKey(myVariant)
@@ -162,13 +162,13 @@ func Test_manager_readRequest(t *testing.T) {
 	_ = theirSIDHPrivKey.Generate(prng)
 	theirSIDHPrivKey.GeneratePublicKey(theirSIDHPubKey)
 
-	_, _ = m.e2e.AddPartner(
+	_, _ = m.getE2eHandler().AddPartner(
 		g.Members[0].ID,
 		g.Members[0].DhKey,
-		m.e2e.GetHistoricalDHPrivkey(),
+		m.getE2eHandler().GetHistoricalDHPrivkey(),
 		theirSIDHPubKey, mySIDHPrivKey,
-		session.GetDefaultParams(),
-		session.GetDefaultParams(),
+		sessionImport.GetDefaultParams(),
+		sessionImport.GetDefaultParams(),
 	)
 
 	requestMarshaled, err := proto.Marshal(&Request{
@@ -201,7 +201,7 @@ func Test_manager_readRequest(t *testing.T) {
 
 // Error path: an error is returned if the message type is incorrect.
 func Test_manager_readRequest_MessageTypeError(t *testing.T) {
-	m, _ := newTestManager(rand.New(rand.NewSource(42)), t)
+	m, _ := newTestManager(t)
 	expectedErr := sendMessageTypeErr
 	msg := receive.Message{
 		MessageType: catalog.NoType,
@@ -217,7 +217,7 @@ func Test_manager_readRequest_MessageTypeError(t *testing.T) {
 // Error path: an error is returned if the proto message cannot be unmarshalled.
 func Test_manager_readRequest_ProtoUnmarshalError(t *testing.T) {
 	expectedErr := strings.SplitN(deserializeMembershipErr, "%", 2)[0]
-	m, _ := newTestManager(rand.New(rand.NewSource(42)), t)
+	m, _ := newTestManager(t)
 
 	requestMarshaled, err := proto.Marshal(&Request{
 		Members: []byte("Invalid membership serial."),
@@ -240,7 +240,7 @@ func Test_manager_readRequest_ProtoUnmarshalError(t *testing.T) {
 
 // Error path: an error is returned if the membership cannot be deserialized.
 func Test_manager_readRequest_DeserializeMembershipError(t *testing.T) {
-	m, _ := newTestManager(rand.New(rand.NewSource(42)), t)
+	m, _ := newTestManager(t)
 	expectedErr := strings.SplitN(protoUnmarshalErr, "%", 2)[0]
 	msg := receive.Message{
 		Payload:     []byte("Invalid message."),
diff --git a/groupChat/send.go b/groupChat/send.go
index 71624079ad5d42f1adce834249f8bdc9965edd4b..efa0e11639c261256fd200cbaac31389b9d7168f 100644
--- a/groupChat/send.go
+++ b/groupChat/send.go
@@ -71,7 +71,7 @@ func (m *manager) Send(groupID *id.ID, tag string, message []byte) (
 
 	// Obtain message ID
 	msgId, err := getGroupMessageId(
-		m.grp, groupID, m.receptionId, timeNow, message)
+		m.getE2eGroup(), groupID, m.getReceptionIdentity().ID, timeNow, message)
 	if err != nil {
 		return 0, time.Time{}, group.MessageID{}, err
 	}
@@ -79,10 +79,10 @@ func (m *manager) Send(groupID *id.ID, tag string, message []byte) (
 	// Send all the groupMessages
 	param := cmix.GetDefaultCMIXParams()
 	param.DebugTag = "group.Message"
-	rid, _, err := m.net.SendMany(groupMessages, param)
+	rid, _, err := m.getCMix().SendMany(groupMessages, param)
 	if err != nil {
 		return 0, time.Time{}, group.MessageID{},
-			errors.Errorf(sendManyCmixErr, m.receptionId, g.Name, g.ID, err)
+			errors.Errorf(sendManyCmixErr, m.getReceptionIdentity().ID, g.Name, g.ID, err)
 	}
 
 	jww.DEBUG.Printf("[GC] Sent message to %d members in group %s at %s.",
@@ -96,19 +96,19 @@ func (m *manager) newMessages(g gs.Group, tag string, msg []byte,
 
 	// Create list of cMix messages
 	messages := make([]cmix.TargetedCmixMessage, 0, len(g.Members))
-	rng := m.rng.GetStream()
+	rng := m.getRng().GetStream()
 	defer rng.Close()
 
 	// Create cMix messages in parallel
 	for _, member := range g.Members {
 		// Do not send to the sender
-		if m.receptionId.Cmp(member.ID) {
+		if m.getReceptionIdentity().ID.Cmp(member.ID) {
 			continue
 		}
 
 		// Add cMix message to list
 		cMixMsg, err := newCmixMsg(g, tag, msg, timestamp, member, rng,
-			m.receptionId, m.net.GetMaxMessageLength())
+			m.getReceptionIdentity().ID, m.getCMix().GetMaxMessageLength())
 		if err != nil {
 			return nil, err
 		}
diff --git a/groupChat/sendRequests.go b/groupChat/sendRequests.go
index dca54c2c951523d6b8af49064f78352d5116ab8b..b28985361e09183b6b4d807e10c770b454386bda 100644
--- a/groupChat/sendRequests.go
+++ b/groupChat/sendRequests.go
@@ -120,7 +120,7 @@ func (m *manager) sendRequest(memberID *id.ID, request []byte) ([]id.Round, erro
 	p.LastServiceTag = catalog.GroupRq
 	p.DebugTag = "group.Request"
 
-	rounds, _, _, err := m.e2e.SendE2E(
+	rounds, _, _, err := m.getE2eHandler().SendE2E(
 		catalog.GroupCreationRequest, memberID, request, p)
 	if err != nil {
 		return nil, errors.Errorf(sendE2eErr, memberID, err)
diff --git a/groupChat/sendRequests_test.go b/groupChat/sendRequests_test.go
index b87e70adbe46899862a6f7ebd304df42076e50b2..bb2589689e40f70b997ddd250da33c50f0c2c99a 100644
--- a/groupChat/sendRequests_test.go
+++ b/groupChat/sendRequests_test.go
@@ -11,7 +11,7 @@ import (
 	"fmt"
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
-	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	sessionImport "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/xx_network/crypto/csprng"
@@ -38,16 +38,16 @@ func Test_manager_ResendRequest(t *testing.T) {
 	}
 
 	for i := range g.Members {
-		grp := m.grp
+		grp := m.getE2eGroup()
 		dhKey := grp.NewInt(int64(i + 42))
 		pubKey := diffieHellman.GeneratePublicKey(dhKey, grp)
-		p := session.GetDefaultParams()
+		p := sessionImport.GetDefaultParams()
 		rng := csprng.NewSystemRNG()
 		_, mySidhPriv := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhA, rng)
 		theirSidhPub, _ := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhB, rng)
-		_, err := m.e2e.AddPartner(g.Members[i].ID, pubKey, dhKey,
+		_, err := m.getE2eHandler().AddPartner(g.Members[i].ID, pubKey, dhKey,
 			mySidhPriv, theirSidhPub, p, p)
 		if err != nil {
 			t.Errorf("Failed to add partner #%d %s: %+v", i, g.Members[i].ID, err)
@@ -64,14 +64,14 @@ func Test_manager_ResendRequest(t *testing.T) {
 			"\nexpected: %s\nreceived: %s", AllSent, status)
 	}
 
-	if len(m.e2e.(*testE2eManager).e2eMessages) < len(g.Members)-1 {
+	if len(m.getE2eHandler().(*testE2eManager).e2eMessages) < len(g.Members)-1 {
 		t.Errorf("ResendRequest() failed to send the correct number of requests."+
 			"\nexpected: %d\nreceived: %d", len(g.Members)-1,
-			len(m.e2e.(*testE2eManager).e2eMessages))
+			len(m.getE2eHandler().(*testE2eManager).e2eMessages))
 	}
 
-	for i := 0; i < len(m.e2e.(*testE2eManager).e2eMessages); i++ {
-		msg := m.e2e.(*testE2eManager).GetE2eMsg(i)
+	for i := 0; i < len(m.getE2eHandler().(*testE2eManager).e2eMessages); i++ {
+		msg := m.getE2eHandler().(*testE2eManager).GetE2eMsg(i)
 
 		// Check if the message recipient is a member in the group
 		matchesMember := false
@@ -134,16 +134,16 @@ func Test_manager_sendRequests(t *testing.T) {
 	}
 
 	for i := range g.Members {
-		grp := m.grp
+		grp := m.getE2eGroup()
 		dhKey := grp.NewInt(int64(i + 42))
 		pubKey := diffieHellman.GeneratePublicKey(dhKey, grp)
-		p := session.GetDefaultParams()
+		p := sessionImport.GetDefaultParams()
 		rng := csprng.NewSystemRNG()
 		_, mySidhPriv := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhA, rng)
 		theirSidhPub, _ := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhB, rng)
-		_, err := m.e2e.AddPartner(g.Members[i].ID, pubKey, dhKey,
+		_, err := m.getE2eHandler().AddPartner(g.Members[i].ID, pubKey, dhKey,
 			mySidhPriv, theirSidhPub, p, p)
 		if err != nil {
 			t.Errorf("Failed to add partner #%d %s: %+v", i, g.Members[i].ID, err)
@@ -160,14 +160,14 @@ func Test_manager_sendRequests(t *testing.T) {
 			"\nexpected: %s\nreceived: %s", AllSent, status)
 	}
 
-	if len(m.e2e.(*testE2eManager).e2eMessages) < len(g.Members)-1 {
+	if len(m.getE2eHandler().(*testE2eManager).e2eMessages) < len(g.Members)-1 {
 		t.Errorf("sendRequests() failed to send the correct number of requests."+
 			"\nexpected: %d\nreceived: %d", len(g.Members)-1,
-			len(m.e2e.(*testE2eManager).e2eMessages))
+			len(m.getE2eHandler().(*testE2eManager).e2eMessages))
 	}
 
-	for i := 0; i < len(m.e2e.(*testE2eManager).e2eMessages); i++ {
-		msg := m.e2e.(*testE2eManager).GetE2eMsg(i)
+	for i := 0; i < len(m.getE2eHandler().(*testE2eManager).e2eMessages); i++ {
+		msg := m.getE2eHandler().(*testE2eManager).GetE2eMsg(i)
 
 		// Check if the message recipient is a member in the group
 		matchesMember := false
@@ -219,9 +219,9 @@ func Test_manager_sendRequests_SendAllFail(t *testing.T) {
 			"\nexpected: %v\nreceived: %v", nil, rounds)
 	}
 
-	if len(m.e2e.(*testE2eManager).e2eMessages) != 0 {
+	if len(m.getE2eHandler().(*testE2eManager).e2eMessages) != 0 {
 		t.Errorf("sendRequests() sent %d messages when sending should have failed.",
-			len(m.e2e.(*testE2eManager).e2eMessages))
+			len(m.getE2eHandler().(*testE2eManager).e2eMessages))
 	}
 }
 
@@ -234,16 +234,16 @@ func Test_manager_sendRequests_SendPartialSent(t *testing.T) {
 		len(g.Members)-1, "")
 
 	for i := range g.Members {
-		grp := m.grp
+		grp := m.getE2eGroup()
 		dhKey := grp.NewInt(int64(i + 42))
 		pubKey := diffieHellman.GeneratePublicKey(dhKey, grp)
-		p := session.GetDefaultParams()
+		p := sessionImport.GetDefaultParams()
 		rng := csprng.NewSystemRNG()
 		_, mySidhPriv := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhA, rng)
 		theirSidhPub, _ := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhB, rng)
-		_, err := m.e2e.AddPartner(g.Members[i].ID, pubKey, dhKey,
+		_, err := m.getE2eHandler().AddPartner(g.Members[i].ID, pubKey, dhKey,
 			mySidhPriv, theirSidhPub, p, p)
 		if err != nil {
 			t.Errorf("Failed to add partner #%d %s: %+v", i, g.Members[i].ID, err)
@@ -261,9 +261,9 @@ func Test_manager_sendRequests_SendPartialSent(t *testing.T) {
 			"\nexpected: %s\nreceived: %s", PartialSent, status)
 	}
 
-	if len(m.e2e.(*testE2eManager).e2eMessages) != (len(g.Members)-1)/2+1 {
+	if len(m.getE2eHandler().(*testE2eManager).e2eMessages) != (len(g.Members)-1)/2+1 {
 		t.Errorf("sendRequests() sent %d out of %d expected messages.",
-			len(m.e2e.(*testE2eManager).e2eMessages), (len(g.Members)-1)/2+1)
+			len(m.getE2eHandler().(*testE2eManager).e2eMessages), (len(g.Members)-1)/2+1)
 	}
 }
 
@@ -273,16 +273,16 @@ func Test_manager_sendRequest(t *testing.T) {
 	m, g := newTestManagerWithStore(prng, 10, 0, nil, t)
 
 	for i := range g.Members {
-		grp := m.grp
+		grp := m.getE2eGroup()
 		dhKey := grp.NewInt(int64(i + 42))
 		pubKey := diffieHellman.GeneratePublicKey(dhKey, grp)
-		p := session.GetDefaultParams()
+		p := sessionImport.GetDefaultParams()
 		rng := csprng.NewSystemRNG()
 		_, mySidhPriv := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhA, rng)
 		theirSidhPub, _ := util.GenerateSIDHKeyPair(
 			sidh.KeyVariantSidhB, rng)
-		_, err := m.e2e.AddPartner(g.Members[i].ID, pubKey, dhKey,
+		_, err := m.getE2eHandler().AddPartner(g.Members[i].ID, pubKey, dhKey,
 			mySidhPriv, theirSidhPub, p, p)
 		if err != nil {
 			t.Errorf("Failed to add partner #%d %s: %+v", i, g.Members[i].ID, err)
@@ -298,7 +298,7 @@ func Test_manager_sendRequest(t *testing.T) {
 		Payload:   []byte("request message"),
 	}
 
-	received := m.e2e.(*testE2eManager).GetE2eMsg(0)
+	received := m.getE2eHandler().(*testE2eManager).GetE2eMsg(0)
 
 	if !reflect.DeepEqual(expected, received) {
 		t.Errorf("sendRequest() did not send the correct message."+
@@ -314,16 +314,16 @@ func Test_manager_sendRequest_SendE2eError(t *testing.T) {
 
 	recipientID := id.NewIdFromString("memberID", id.User, t)
 
-	grp := m.grp
+	grp := m.getE2eGroup()
 	dhKey := grp.NewInt(int64(42))
 	pubKey := diffieHellman.GeneratePublicKey(dhKey, grp)
-	p := session.GetDefaultParams()
+	p := sessionImport.GetDefaultParams()
 	rng := csprng.NewSystemRNG()
 	_, mySidhPriv := util.GenerateSIDHKeyPair(
 		sidh.KeyVariantSidhA, rng)
 	theirSidhPub, _ := util.GenerateSIDHKeyPair(
 		sidh.KeyVariantSidhB, rng)
-	_, err := m.e2e.AddPartner(recipientID, pubKey, dhKey,
+	_, err := m.getE2eHandler().AddPartner(recipientID, pubKey, dhKey,
 		mySidhPriv, theirSidhPub, p, p)
 	if err != nil {
 		t.Errorf("Failed to add partner %s: %+v", recipientID, err)
diff --git a/groupChat/send_test.go b/groupChat/send_test.go
index 71e252e5835ba1834f6108dbba0e6e813884df0b..be68cb2e8bccca341785038e8596302ba63ba9d5 100644
--- a/groupChat/send_test.go
+++ b/groupChat/send_test.go
@@ -44,8 +44,8 @@ func Test_manager_Send(t *testing.T) {
 
 	// Get messages sent with or return an error if no messages were sent
 	var messages []format.Message
-	if len(m.net.(*testNetworkManager).receptionMessages) > 0 {
-		messages = m.net.(*testNetworkManager).receptionMessages[0]
+	if len(m.getCMix().(*testNetworkManager).receptionMessages) > 0 {
+		messages = m.getCMix().(*testNetworkManager).receptionMessages[0]
 	} else {
 		t.Error("No group cMix messages received.")
 	}
@@ -59,7 +59,7 @@ func Test_manager_Send(t *testing.T) {
 			rounds.Round{ID: roundId, Timestamps: timestamps})
 		select {
 		case result := <-msgChan:
-			if !result.SenderID.Cmp(m.receptionId) {
+			if !result.SenderID.Cmp(m.getReceptionIdentity().ID) {
 				t.Errorf("Sender mismatch")
 			}
 			if result.ID.String() != msgId.String() {
@@ -75,12 +75,12 @@ func Test_manager_Send(t *testing.T) {
 // Error path: reader returns an error.
 func TestGroup_newCmixMsg_SaltReaderError(t *testing.T) {
 	expectedErr := strings.SplitN(saltReadErr, "%", 2)[0]
-	m, _ := newTestManager(rand.New(rand.NewSource(42)), t)
+	m, _ := newTestManager(t)
 
 	_, err := newCmixMsg(
 		gs.Group{ID: id.NewIdFromString("test", id.User, t)}, "",
 		[]byte{}, time.Time{}, group.Member{}, strings.NewReader(""),
-		m.receptionId, m.net.GetMaxMessageLength())
+		m.getReceptionIdentity().ID, m.getCMix().GetMaxMessageLength())
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("newCmixMsg failed to return the expected error"+
 			"\nexpected: %s\nreceived: %+v", expectedErr, err)
@@ -102,7 +102,7 @@ func TestGroup_newCmixMsg_InternalMsgSizeError(t *testing.T) {
 	// Create cMix message
 	prng = rand.New(rand.NewSource(42))
 	_, err := newCmixMsg(g, "", testMsg, netTime.Now(), mem, prng,
-		m.receptionId, m.net.GetMaxMessageLength())
+		m.getReceptionIdentity().ID, m.getCMix().GetMaxMessageLength())
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("newCmixMsg failed to return the expected error"+
 			"\nexpected: %s\nreceived: %+v", expectedErr, err)
diff --git a/groupChat/service.go b/groupChat/service.go
index db893354a1bad3cdd7885cc3f6ef8c5b87ff40e8..d2a5916aaa7975a8d20065f88ce0a9047bbbed74 100644
--- a/groupChat/service.go
+++ b/groupChat/service.go
@@ -39,7 +39,8 @@ func (m *manager) AddService(tag string, p Processor) error {
 	// Add a service for every group
 	for _, g := range m.gs.Groups() {
 		newService := makeService(g.ID, tag)
-		m.net.AddService(m.receptionId, newService, &receptionProcessor{m, g, p})
+		m.getCMix().AddService(m.getReceptionIdentity().ID, newService,
+			&receptionProcessor{m, g, p})
 	}
 
 	return nil
@@ -60,7 +61,8 @@ func (m *manager) RemoveService(tag string) error {
 	// Delete service for every group
 	for _, g := range m.gs.Groups() {
 		toDelete := makeService(g.ID, tag)
-		m.net.DeleteService(m.receptionId, toDelete, &receptionProcessor{m, g, oldProcess})
+		m.getCMix().DeleteService(m.getReceptionIdentity().ID, toDelete,
+			&receptionProcessor{m, g, oldProcess})
 	}
 
 	return nil
@@ -70,7 +72,8 @@ func (m *manager) RemoveService(tag string) error {
 func (m *manager) addAllServices(g gs.Group) {
 	for tag, p := range m.services {
 		newService := makeService(g.ID, tag)
-		m.net.AddService(m.receptionId, newService, &receptionProcessor{m, g, p})
+		m.getCMix().AddService(m.getReceptionIdentity().ID, newService,
+			&receptionProcessor{m, g, p})
 	}
 }
 
@@ -78,7 +81,7 @@ func (m *manager) addAllServices(g gs.Group) {
 func (m *manager) deleteAllServices(groupID *id.ID) {
 	for tag := range m.services {
 		toDelete := makeService(groupID, tag)
-		m.net.DeleteService(m.receptionId, toDelete, nil)
+		m.getCMix().DeleteService(m.getReceptionIdentity().ID, toDelete, nil)
 	}
 }
 
diff --git a/groupChat/session_test.go b/groupChat/session_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..15877e7af4c0afcb9a7b8276810ebdd21b91eb26
--- /dev/null
+++ b/groupChat/session_test.go
@@ -0,0 +1,174 @@
+package groupChat
+
+import (
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/client/storage/user"
+	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/ekv"
+	"gitlab.com/elixxir/primitives/version"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/ndf"
+	"time"
+)
+
+// mockSession is a storage.Session implementation for testing.
+type mockSession struct {
+	kv *versioned.KV
+}
+
+func newMockSesion(kv *versioned.KV) storage.Session {
+	return mockSession{kv: kv}
+}
+
+func (m mockSession) GetE2EGroup() *cyclic.Group {
+	return getGroup()
+}
+
+func (m mockSession) GetKV() *versioned.KV {
+	if m.kv != nil {
+		return m.kv
+	}
+
+	return versioned.NewKV(ekv.MakeMemstore())
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Unused & unimplemented methods of the test object ////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+
+func (m mockSession) GetClientVersion() version.Version {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) Get(key string) (*versioned.Object, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) Set(key string, object *versioned.Object) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) Delete(key string) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetCmixGroup() *cyclic.Group {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) ForwardRegistrationStatus(regStatus storage.RegistrationStatus) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetRegistrationStatus() storage.RegistrationStatus {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) SetRegCode(regCode string) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetRegCode() (string, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) SetNDF(def *ndf.NetworkDefinition) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetNDF() *ndf.NetworkDefinition {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetTransmissionID() *id.ID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetTransmissionSalt() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetReceptionID() *id.ID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetReceptionSalt() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetReceptionRSA() *rsa.PrivateKey {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetTransmissionRSA() *rsa.PrivateKey {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) IsPrecanned() bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) SetUsername(username string) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetUsername() (string, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) PortableUserInfo() user.Info {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetTransmissionRegistrationValidationSignature() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetReceptionRegistrationValidationSignature() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) GetRegistrationTimestamp() time.Time {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) SetTransmissionRegistrationValidationSignature(b []byte) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) SetReceptionRegistrationValidationSignature(b []byte) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockSession) SetRegistrationTimestamp(tsNano int64) {
+	//TODO implement me
+	panic("implement me")
+}
diff --git a/groupChat/utils_test.go b/groupChat/utils_test.go
index 7b9778e10938f4d626594543ad7f609c704702f5..f672c61cc117d7dfa2b2d55d50ce50fdee44c819 100644
--- a/groupChat/utils_test.go
+++ b/groupChat/utils_test.go
@@ -9,54 +9,41 @@ package groupChat
 
 import (
 	"encoding/base64"
-	"math/rand"
-	"sync"
-	"testing"
-	"time"
-
-	"github.com/cloudflare/circl/dh/sidh"
-	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/catalog"
-	"gitlab.com/elixxir/client/cmix"
-	"gitlab.com/elixxir/client/cmix/message"
-	clientE2E "gitlab.com/elixxir/client/e2e"
 	"gitlab.com/elixxir/client/e2e/ratchet/partner"
-	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
-	"gitlab.com/elixxir/client/e2e/receive"
 	"gitlab.com/elixxir/client/event"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/e2e"
-	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/ekv"
-	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/crypto/large"
 	"gitlab.com/xx_network/primitives/id"
-	"gitlab.com/xx_network/primitives/id/ephemeral"
 	"gitlab.com/xx_network/primitives/ndf"
 	"gitlab.com/xx_network/primitives/netTime"
+	"math/rand"
+	"testing"
 )
 
+/////////////////////////////////////////////////////////////////////////////////////////
+// mock manager implementation //////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
 // newTestManager creates a new manager for testing.
-func newTestManager(rng *rand.Rand, t *testing.T) (*manager, gs.Group) {
+func newTestManager(t testing.TB) (*manager, gs.Group) {
+	prng := rand.New(rand.NewSource(42))
+	mockMess := newMockMessenger(t, nil)
+
 	m := &manager{
-		receptionId: id.NewIdFromString("test", id.User, t),
-		net:         newTestNetworkManager(0, t),
-		e2e:         newTestE2eManager(randCycInt(rng)),
-		grp:         getGroup(),
-		rng:         fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG),
+		messenger: mockMess,
 	}
 	user := group.Member{
-		ID:    m.receptionId,
-		DhKey: m.e2e.GetHistoricalDHPubkey(),
+		ID:    m.getReceptionIdentity().ID,
+		DhKey: m.getE2eHandler().GetHistoricalDHPubkey(),
 	}
 
-	g := newTestGroupWithUser(m.grp, user.ID, user.DhKey,
-		m.e2e.GetHistoricalDHPrivkey(), rng, t)
+	g := newTestGroupWithUser(m.getE2eGroup(), user.ID, user.DhKey,
+		m.getE2eHandler().GetHistoricalDHPrivkey(), prng, t)
 	gStore, err := gs.NewStore(versioned.NewKV(ekv.MakeMemstore()), user)
 	if err != nil {
 		t.Fatalf("Failed to create new group store: %+v", err)
@@ -70,25 +57,16 @@ func newTestManager(rng *rand.Rand, t *testing.T) (*manager, gs.Group) {
 // of the groups in the list is also returned.
 func newTestManagerWithStore(rng *rand.Rand, numGroups int, sendErr int,
 	requestFunc RequestCallback, t *testing.T) (*manager, gs.Group) {
+	mockMess := newMockMessengerWithStore(t, sendErr)
 
 	m := &manager{
 		services:    make(map[string]Processor),
 		requestFunc: requestFunc,
-		receptionId: id.NewIdFromString("test", id.User, t),
-		net:         newTestNetworkManager(sendErr, t),
-		e2e: &testE2eManager{
-			e2eMessages: []testE2eMessage{},
-			sendErr:     sendErr,
-			grp:         getGroup(),
-			dhPubKey:    randCycInt(rng),
-			partners:    make(map[id.ID]partner.Manager),
-		},
-		grp: getGroup(),
-		rng: fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG),
+		messenger:   mockMess,
 	}
 	user := group.Member{
-		ID:    m.receptionId,
-		DhKey: m.e2e.GetHistoricalDHPubkey(),
+		ID:    m.getReceptionIdentity().ID,
+		DhKey: m.getE2eHandler().GetHistoricalDHPubkey(),
 	}
 
 	gStore, err := gs.NewStore(versioned.NewKV(ekv.MakeMemstore()), user)
@@ -99,7 +77,7 @@ func newTestManagerWithStore(rng *rand.Rand, numGroups int, sendErr int,
 
 	var g gs.Group
 	for i := 0; i < numGroups; i++ {
-		g = newTestGroupWithUser(m.grp, user.ID, user.DhKey,
+		g = newTestGroupWithUser(m.getE2eGroup(), user.ID, user.DhKey,
 			randCycInt(rng), rng, t)
 		if err = gStore.Add(g); err != nil {
 			t.Fatalf("Failed to add group %d to group store: %+v", i, err)
@@ -108,7 +86,7 @@ func newTestManagerWithStore(rng *rand.Rand, numGroups int, sendErr int,
 	return m, g
 }
 
-func newTestE2eManager(dhPubKey *cyclic.Int) *testE2eManager {
+func newTestE2eManager(dhPubKey *cyclic.Int, t testing.TB) *testE2eManager {
 	return &testE2eManager{
 		e2eMessages: []testE2eMessage{},
 		errSkip:     0,
@@ -120,7 +98,7 @@ func newTestE2eManager(dhPubKey *cyclic.Int) *testE2eManager {
 
 // getMembership returns a Membership with random members for testing.
 func getMembership(size int, uid *id.ID, pubKey *cyclic.Int, grp *cyclic.Group,
-	prng *rand.Rand, t *testing.T) group.Membership {
+	prng *rand.Rand, t testing.TB) group.Membership {
 	contacts := make([]contact.Contact, size)
 	for i := range contacts {
 		randId, _ := id.NewRandomID(prng, id.User)
@@ -179,7 +157,7 @@ func newTestGroup(grp *cyclic.Group, privKey *cyclic.Int, rng *rand.Rand,
 
 // newTestGroup generates a new group with random values for testing.
 func newTestGroupWithUser(grp *cyclic.Group, uid *id.ID, pubKey,
-	privKey *cyclic.Int, rng *rand.Rand, t *testing.T) gs.Group {
+	privKey *cyclic.Int, rng *rand.Rand, t testing.TB) gs.Group {
 	// Generate name from base 64 encoded random data
 	nameBytes := make([]byte, 16)
 	rng.Read(nameBytes)
@@ -222,137 +200,6 @@ func getGroup() *cyclic.Group {
 		large.NewIntFromString(getNDF().E2E.Generator, 16))
 }
 
-func newTestNetworkManager(sendErr int, _ *testing.T) GroupCmix {
-	return &testNetworkManager{
-		receptionMessages: [][]format.Message{},
-		sendMessages:      [][]cmix.TargetedCmixMessage{},
-		grp:               getGroup(),
-		sendErr:           sendErr,
-	}
-}
-
-// testE2eManager is a test implementation of NetworkManager interface.
-type testE2eManager struct {
-	e2eMessages []testE2eMessage
-	partners    map[id.ID]partner.Manager
-	errSkip     int
-	sendErr     int
-	dhPubKey    *cyclic.Int
-	grp         *cyclic.Group
-	sync.RWMutex
-}
-
-type testE2eMessage struct {
-	Recipient *id.ID
-	Payload   []byte
-}
-
-func (tnm *testE2eManager) AddPartner(partnerID *id.ID, partnerPubKey,
-	myPrivKey *cyclic.Int, _ *sidh.PublicKey, _ *sidh.PrivateKey,
-	_, _ session.Params) (partner.Manager, error) {
-
-	testPartner := partner.NewTestManager(partnerID, partnerPubKey, myPrivKey, &testing.T{})
-	tnm.partners[*partnerID] = testPartner
-	return testPartner, nil
-}
-
-func (tnm *testE2eManager) GetPartner(partnerID *id.ID) (partner.Manager, error) {
-	if p, ok := tnm.partners[*partnerID]; ok {
-		return p, nil
-	}
-	return nil, errors.New("Unable to find partner")
-}
-
-func (tnm *testE2eManager) GetHistoricalDHPubkey() *cyclic.Int {
-	return tnm.dhPubKey
-}
-
-func (tnm *testE2eManager) GetHistoricalDHPrivkey() *cyclic.Int {
-	return tnm.dhPubKey
-}
-
-func (tnm *testE2eManager) SendE2E(_ catalog.MessageType, recipient *id.ID,
-	payload []byte, _ clientE2E.Params) ([]id.Round, e2e.MessageID, time.Time,
-	error) {
-	tnm.Lock()
-	defer tnm.Unlock()
-
-	tnm.errSkip++
-	if tnm.sendErr == 1 {
-		return nil, e2e.MessageID{}, time.Time{}, errors.New("SendE2E error")
-	} else if tnm.sendErr == 2 && tnm.errSkip%2 == 0 {
-		return nil, e2e.MessageID{}, time.Time{}, errors.New("SendE2E error")
-	}
-
-	tnm.e2eMessages = append(tnm.e2eMessages, testE2eMessage{
-		Recipient: recipient,
-		Payload:   payload,
-	})
-
-	return []id.Round{0, 1, 2, 3}, e2e.MessageID{}, time.Time{}, nil
-}
-
-func (*testE2eManager) RegisterListener(*id.ID, catalog.MessageType, receive.Listener) receive.ListenerID {
-	return receive.ListenerID{}
-}
-
-func (*testE2eManager) AddService(string, message.Processor) error {
-	return nil
-}
-
-func (*testE2eManager) GetDefaultHistoricalDHPubkey() *cyclic.Int {
-	panic("implement me")
-}
-
-func (*testE2eManager) GetDefaultHistoricalDHPrivkey() *cyclic.Int {
-	panic("implement me")
-}
-
-func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage {
-	tnm.RLock()
-	defer tnm.RUnlock()
-	return tnm.e2eMessages[i]
-}
-
-// testNetworkManager is a test implementation of NetworkManager interface.
-type testNetworkManager struct {
-	receptionMessages [][]format.Message
-	sendMessages      [][]cmix.TargetedCmixMessage
-	errSkip           int
-	sendErr           int
-	grp               *cyclic.Group
-	sync.RWMutex
-}
-
-func (tnm *testNetworkManager) GetMaxMessageLength() int {
-	return format.NewMessage(tnm.grp.GetP().ByteLen()).ContentsSize()
-}
-
-func (tnm *testNetworkManager) SendMany(messages []cmix.TargetedCmixMessage, _ cmix.CMIXParams) (id.Round, []ephemeral.Id, error) {
-	if tnm.sendErr == 1 {
-		return 0, nil, errors.New("SendManyCMIX error")
-	}
-
-	tnm.Lock()
-	defer tnm.Unlock()
-
-	tnm.sendMessages = append(tnm.sendMessages, messages)
-
-	var receiveMessages []format.Message
-	for _, msg := range messages {
-		receiveMsg := format.NewMessage(tnm.grp.GetP().ByteLen())
-		receiveMsg.SetMac(msg.Mac)
-		receiveMsg.SetContents(msg.Payload)
-		receiveMsg.SetKeyFP(msg.Fingerprint)
-		receiveMessages = append(receiveMessages, receiveMsg)
-	}
-	tnm.receptionMessages = append(tnm.receptionMessages, receiveMessages)
-	return 0, nil, nil
-}
-
-func (*testNetworkManager) AddService(*id.ID, message.Service, message.Processor)    {}
-func (*testNetworkManager) DeleteService(*id.ID, message.Service, message.Processor) {}
-
 type dummyEventMgr struct{}
 
 func (d *dummyEventMgr) Report(int, string, string, string) {}