diff --git a/state/syncer/baseAccoutnsSyncer_test.go b/state/syncer/baseAccoutnsSyncer_test.go
new file mode 100644
index 00000000000..12ba52df5fe
--- /dev/null
+++ b/state/syncer/baseAccoutnsSyncer_test.go
@@ -0,0 +1,114 @@
+package syncer_test
+
+import (
+	"testing"
+	"time"
+
+	"github.com/multiversx/mx-chain-go/state"
+	"github.com/multiversx/mx-chain-go/state/syncer"
+	"github.com/multiversx/mx-chain-go/testscommon"
+	"github.com/multiversx/mx-chain-go/testscommon/hashingMocks"
+	"github.com/multiversx/mx-chain-go/testscommon/statusHandler"
+	"github.com/multiversx/mx-chain-go/trie/storageMarker"
+	"github.com/stretchr/testify/require"
+)
+
+func getDefaultBaseAccSyncerArgs() syncer.ArgsNewBaseAccountsSyncer {
+	return syncer.ArgsNewBaseAccountsSyncer{
+		Hasher:                            &hashingMocks.HasherMock{},
+		Marshalizer:                       testscommon.MarshalizerMock{},
+		TrieStorageManager:                &testscommon.StorageManagerStub{},
+		StorageMarker:                     storageMarker.NewDisabledStorageMarker(),
+		RequestHandler:                    &testscommon.RequestHandlerStub{},
+		Timeout:                           time.Second,
+		Cacher:                            testscommon.NewCacherMock(),
+		UserAccountsSyncStatisticsHandler: &testscommon.SizeSyncStatisticsHandlerStub{},
+		AppStatusHandler:                  &statusHandler.AppStatusHandlerStub{},
+		MaxTrieLevelInMemory:              5,
+		MaxHardCapForMissingNodes:         100,
+		TrieSyncerVersion:                 3,
+		CheckNodesOnDisk:                  false,
+	}
+}
+
+func TestBaseAccountsSyncer_CheckArgs(t *testing.T) {
+	t.Parallel()
+
+	t.Run("nil hasher", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.Hasher = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilHasher, err)
+	})
+
+	t.Run("nil marshaller", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.Marshalizer = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilMarshalizer, err)
+	})
+
+	t.Run("nil trie storage manager", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.TrieStorageManager = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilStorageManager, err)
+	})
+
+	t.Run("nil requests handler", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.RequestHandler = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilRequestHandler, err)
+	})
+
+	t.Run("nil cacher", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.Cacher = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilCacher, err)
+	})
+
+	t.Run("nil user accounts sync statistics handler", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.UserAccountsSyncStatisticsHandler = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilSyncStatisticsHandler, err)
+	})
+
+	t.Run("nil app status handler", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.AppStatusHandler = nil
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrNilAppStatusHandler, err)
+	})
+
+	t.Run("invalid max hard capacity for missing nodes", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultBaseAccSyncerArgs()
+		args.MaxHardCapForMissingNodes = 0
+		err := syncer.CheckBaseAccountsSyncerArgs(args)
+		require.Equal(t, state.ErrInvalidMaxHardCapForMissingNodes, err)
+	})
+
+	t.Run("should work", func(t *testing.T) {
+		t.Parallel()
+
+		require.Nil(t, syncer.CheckBaseAccountsSyncerArgs(getDefaultBaseAccSyncerArgs()))
+	})
+}
diff --git a/state/syncer/export_test.go b/state/syncer/export_test.go
new file mode 100644
index 00000000000..dcea224d65e
--- /dev/null
+++ b/state/syncer/export_test.go
@@ -0,0 +1,26 @@
+package syncer
+
+import (
+	"context"
+
+	"github.com/multiversx/mx-chain-go/common"
+)
+
+// UserAccountsSyncer -
+type UserAccountsSyncer = userAccountsSyncer
+
+// ValidatorAccountsSyncer -
+type ValidatorAccountsSyncer = validatorAccountsSyncer
+
+// CheckBaseAccountsSyncerArgs -
+func CheckBaseAccountsSyncerArgs(args ArgsNewBaseAccountsSyncer) error {
+	return checkArgs(args)
+}
+
+// SyncAccountDataTries -
+func (u *userAccountsSyncer) SyncAccountDataTries(
+	mainTrie common.Trie,
+	ctx context.Context,
+) error {
+	return u.syncAccountDataTries(mainTrie, ctx)
+}
diff --git a/state/syncer/userAccountsSyncer_test.go b/state/syncer/userAccountsSyncer_test.go
new file mode 100644
index 00000000000..f0080682107
--- /dev/null
+++ b/state/syncer/userAccountsSyncer_test.go
@@ -0,0 +1,317 @@
+package syncer_test
+
+import (
+	"context"
+	"errors"
+	"testing"
+	"time"
+
+	"github.com/multiversx/mx-chain-core-go/data"
+	"github.com/multiversx/mx-chain-core-go/hashing"
+	"github.com/multiversx/mx-chain-core-go/marshal"
+	"github.com/multiversx/mx-chain-go/api/mock"
+	"github.com/multiversx/mx-chain-go/common"
+	"github.com/multiversx/mx-chain-go/config"
+	"github.com/multiversx/mx-chain-go/state"
+	"github.com/multiversx/mx-chain-go/state/syncer"
+	"github.com/multiversx/mx-chain-go/testscommon"
+	trieMocks "github.com/multiversx/mx-chain-go/testscommon/trie"
+	"github.com/multiversx/mx-chain-go/trie"
+	"github.com/multiversx/mx-chain-go/trie/hashesHolder"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func getDefaultUserAccountsSyncerArgs() syncer.ArgsNewUserAccountsSyncer {
+	return syncer.ArgsNewUserAccountsSyncer{
+		ArgsNewBaseAccountsSyncer: getDefaultBaseAccSyncerArgs(),
+		ShardId:                   1,
+		Throttler:                 &mock.ThrottlerStub{},
+		AddressPubKeyConverter:    &testscommon.PubkeyConverterStub{},
+	}
+}
+
+func TestNewUserAccountsSyncer(t *testing.T) {
+	t.Parallel()
+
+	t.Run("invalid base args (nil hasher) should fail", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		args.Hasher = nil
+
+		syncer, err := syncer.NewUserAccountsSyncer(args)
+		assert.Nil(t, syncer)
+		assert.Equal(t, state.ErrNilHasher, err)
+	})
+
+	t.Run("nil throttler", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		args.Throttler = nil
+
+		syncer, err := syncer.NewUserAccountsSyncer(args)
+		assert.Nil(t, syncer)
+		assert.Equal(t, data.ErrNilThrottler, err)
+	})
+
+	t.Run("nil address pubkey converter", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		args.AddressPubKeyConverter = nil
+
+		s, err := syncer.NewUserAccountsSyncer(args)
+		assert.Nil(t, s)
+		assert.Equal(t, syncer.ErrNilPubkeyConverter, err)
+	})
+
+	t.Run("invalid timeout, should fail", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		args.Timeout = 0
+
+		s, err := syncer.NewUserAccountsSyncer(args)
+		assert.Nil(t, s)
+		assert.True(t, errors.Is(err, common.ErrInvalidTimeout))
+	})
+
+	t.Run("should work", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		syncer, err := syncer.NewUserAccountsSyncer(args)
+		assert.Nil(t, err)
+		assert.NotNil(t, syncer)
+	})
+}
+
+func getSerializedTrieNode(
+	key []byte,
+	marshaller marshal.Marshalizer,
+	hasher hashing.Hasher,
+) []byte {
+	var serializedLeafNode []byte
+	tsm := &testscommon.StorageManagerStub{
+		PutCalled: func(key []byte, val []byte) error {
+			serializedLeafNode = val
+			return nil
+		},
+	}
+
+	tr, _ := trie.NewTrie(tsm, marshaller, hasher, 5)
+	_ = tr.Update(key, []byte("value"))
+	_ = tr.Commit()
+
+	return serializedLeafNode
+}
+
+func TestUserAccountsSyncer_SyncAccounts(t *testing.T) {
+	t.Parallel()
+
+	args := getDefaultUserAccountsSyncerArgs()
+	args.Timeout = 5 * time.Second
+
+	key := []byte("rootHash")
+	serializedLeafNode := getSerializedTrieNode(key, args.Marshalizer, args.Hasher)
+	itn, err := trie.NewInterceptedTrieNode(serializedLeafNode, args.Hasher)
+	require.Nil(t, err)
+
+	args.TrieStorageManager = &testscommon.StorageManagerStub{
+		GetCalled: func(b []byte) ([]byte, error) {
+			return serializedLeafNode, nil
+		},
+	}
+
+	cacher := testscommon.NewCacherMock()
+	cacher.Put(key, itn, 0)
+	args.Cacher = cacher
+
+	s, err := syncer.NewUserAccountsSyncer(args)
+	require.Nil(t, err)
+
+	err = s.SyncAccounts(key)
+	require.Nil(t, err)
+}
+
+func getDefaultTrieParameters() (common.StorageManager, marshal.Marshalizer, hashing.Hasher, uint) {
+	marshalizer := &testscommon.ProtobufMarshalizerMock{}
+	hasher := &testscommon.KeccakMock{}
+
+	generalCfg := config.TrieStorageManagerConfig{
+		PruningBufferLen:      1000,
+		SnapshotsBufferLen:    10,
+		SnapshotsGoroutineNum: 1,
+	}
+
+	args := trie.NewTrieStorageManagerArgs{
+		MainStorer:             testscommon.NewSnapshotPruningStorerMock(),
+		CheckpointsStorer:      testscommon.NewSnapshotPruningStorerMock(),
+		Marshalizer:            marshalizer,
+		Hasher:                 hasher,
+		GeneralConfig:          generalCfg,
+		CheckpointHashesHolder: hashesHolder.NewCheckpointHashesHolder(10000000, testscommon.HashSize),
+		IdleProvider:           &testscommon.ProcessStatusHandlerStub{},
+	}
+
+	trieStorageManager, _ := trie.NewTrieStorageManager(args)
+	maxTrieLevelInMemory := uint(1)
+
+	return trieStorageManager, args.Marshalizer, args.Hasher, maxTrieLevelInMemory
+}
+
+func emptyTrie() common.Trie {
+	tr, _ := trie.NewTrie(getDefaultTrieParameters())
+
+	return tr
+}
+
+func TestUserAccountsSyncer_SyncAccountDataTries(t *testing.T) {
+	t.Parallel()
+
+	t.Run("failed to get trie root hash", func(t *testing.T) {
+		t.Parallel()
+
+		expectedErr := errors.New("expected err")
+		tr := &trieMocks.TrieStub{
+			RootCalled: func() ([]byte, error) {
+				return nil, expectedErr
+			},
+		}
+
+		args := getDefaultUserAccountsSyncerArgs()
+		s, err := syncer.NewUserAccountsSyncer(args)
+		require.Nil(t, err)
+
+		err = s.SyncAccountDataTries(tr, context.TODO())
+		require.Equal(t, expectedErr, err)
+	})
+
+	t.Run("failed to get all leaves on channel", func(t *testing.T) {
+		t.Parallel()
+
+		expectedErr := errors.New("expected err")
+		tr := &trieMocks.TrieStub{
+			RootCalled: func() ([]byte, error) {
+				return []byte("rootHash"), nil
+			},
+			GetAllLeavesOnChannelCalled: func(leavesChannels *common.TrieIteratorChannels, ctx context.Context, rootHash []byte, keyBuilder common.KeyBuilder) error {
+				return expectedErr
+			},
+		}
+
+		args := getDefaultUserAccountsSyncerArgs()
+		s, err := syncer.NewUserAccountsSyncer(args)
+		require.Nil(t, err)
+
+		err = s.SyncAccountDataTries(tr, context.TODO())
+		require.Equal(t, expectedErr, err)
+	})
+
+	t.Run("throttler cannot process and closed context should fail", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		args.Timeout = 5 * time.Second
+
+		key := []byte("accRootHash")
+		serializedLeafNode := getSerializedTrieNode(key, args.Marshalizer, args.Hasher)
+		itn, err := trie.NewInterceptedTrieNode(serializedLeafNode, args.Hasher)
+		require.Nil(t, err)
+
+		args.TrieStorageManager = &testscommon.StorageManagerStub{
+			GetCalled: func(b []byte) ([]byte, error) {
+				return serializedLeafNode, nil
+			},
+		}
+		args.Throttler = &mock.ThrottlerStub{
+			CanProcessCalled: func() bool {
+				return false
+			},
+		}
+
+		cacher := testscommon.NewCacherMock()
+		cacher.Put(key, itn, 0)
+		args.Cacher = cacher
+
+		s, err := syncer.NewUserAccountsSyncer(args)
+		require.Nil(t, err)
+
+		_, _ = trie.NewTrie(args.TrieStorageManager, args.Marshalizer, args.Hasher, 5)
+		tr := emptyTrie()
+
+		account, err := state.NewUserAccount(testscommon.TestPubKeyAlice)
+		require.Nil(t, err)
+		account.SetRootHash(key)
+
+		accountBytes, err := args.Marshalizer.Marshal(account)
+		require.Nil(t, err)
+
+		_ = tr.Update([]byte("doe"), []byte("reindeer"))
+		_ = tr.Update([]byte("dog"), []byte("puppy"))
+		_ = tr.Update([]byte("ddog"), accountBytes)
+		_ = tr.Commit()
+
+		ctx, cancel := context.WithCancel(context.TODO())
+		cancel()
+
+		err = s.SyncAccountDataTries(tr, ctx)
+		require.Equal(t, data.ErrTimeIsOut, err)
+	})
+
+	t.Run("should work", func(t *testing.T) {
+		t.Parallel()
+
+		args := getDefaultUserAccountsSyncerArgs()
+		args.Timeout = 5 * time.Second
+
+		key := []byte("accRootHash")
+		serializedLeafNode := getSerializedTrieNode(key, args.Marshalizer, args.Hasher)
+		itn, err := trie.NewInterceptedTrieNode(serializedLeafNode, args.Hasher)
+		require.Nil(t, err)
+
+		args.TrieStorageManager = &testscommon.StorageManagerStub{
+			GetCalled: func(b []byte) ([]byte, error) {
+				return serializedLeafNode, nil
+			},
+		}
+
+		cacher := testscommon.NewCacherMock()
+		cacher.Put(key, itn, 0)
+		args.Cacher = cacher
+
+		s, err := syncer.NewUserAccountsSyncer(args)
+		require.Nil(t, err)
+
+		_, _ = trie.NewTrie(args.TrieStorageManager, args.Marshalizer, args.Hasher, 5)
+		tr := emptyTrie()
+
+		account, err := state.NewUserAccount(testscommon.TestPubKeyAlice)
+		require.Nil(t, err)
+		account.SetRootHash(key)
+
+		accountBytes, err := args.Marshalizer.Marshal(account)
+		require.Nil(t, err)
+
+		_ = tr.Update([]byte("doe"), []byte("reindeer"))
+		_ = tr.Update([]byte("dog"), []byte("puppy"))
+		_ = tr.Update([]byte("ddog"), accountBytes)
+		_ = tr.Commit()
+
+		err = s.SyncAccountDataTries(tr, context.TODO())
+		require.Nil(t, err)
+	})
+}
+
+func TestUserAccountsSyncer_IsInterfaceNil(t *testing.T) {
+	t.Parallel()
+
+	var uas *syncer.UserAccountsSyncer
+	assert.True(t, uas.IsInterfaceNil())
+
+	uas, err := syncer.NewUserAccountsSyncer(getDefaultUserAccountsSyncerArgs())
+	require.Nil(t, err)
+	assert.False(t, uas.IsInterfaceNil())
+}
diff --git a/state/syncer/validatorAccountsSyncer_test.go b/state/syncer/validatorAccountsSyncer_test.go
new file mode 100644
index 00000000000..cdb33719c4d
--- /dev/null
+++ b/state/syncer/validatorAccountsSyncer_test.go
@@ -0,0 +1,98 @@
+package syncer_test
+
+import (
+	"errors"
+	"testing"
+
+	"github.com/multiversx/mx-chain-go/common"
+	"github.com/multiversx/mx-chain-go/state"
+	"github.com/multiversx/mx-chain-go/state/syncer"
+	"github.com/multiversx/mx-chain-go/testscommon"
+	"github.com/multiversx/mx-chain-go/trie"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestNewValidatorAccountsSyncer(t *testing.T) {
+	t.Parallel()
+
+	t.Run("invalid base args (nil hasher) should fail", func(t *testing.T) {
+		t.Parallel()
+
+		args := syncer.ArgsNewValidatorAccountsSyncer{
+			ArgsNewBaseAccountsSyncer: getDefaultBaseAccSyncerArgs(),
+		}
+		args.Hasher = nil
+
+		syncer, err := syncer.NewValidatorAccountsSyncer(args)
+		assert.Nil(t, syncer)
+		assert.Equal(t, state.ErrNilHasher, err)
+	})
+
+	t.Run("invalid timeout, should fail", func(t *testing.T) {
+		t.Parallel()
+
+		args := syncer.ArgsNewValidatorAccountsSyncer{
+			ArgsNewBaseAccountsSyncer: getDefaultBaseAccSyncerArgs(),
+		}
+		args.Timeout = 0
+
+		s, err := syncer.NewValidatorAccountsSyncer(args)
+		assert.Nil(t, s)
+		assert.True(t, errors.Is(err, common.ErrInvalidTimeout))
+	})
+
+	t.Run("should work", func(t *testing.T) {
+		t.Parallel()
+
+		args := syncer.ArgsNewValidatorAccountsSyncer{
+			ArgsNewBaseAccountsSyncer: getDefaultBaseAccSyncerArgs(),
+		}
+		v, err := syncer.NewValidatorAccountsSyncer(args)
+		require.Nil(t, err)
+		require.NotNil(t, v)
+	})
+}
+
+func TestValidatorAccountsSyncer_SyncAccounts(t *testing.T) {
+	t.Parallel()
+
+	args := syncer.ArgsNewValidatorAccountsSyncer{
+		ArgsNewBaseAccountsSyncer: getDefaultBaseAccSyncerArgs(),
+	}
+
+	key := []byte("rootHash")
+	serializedLeafNode := getSerializedTrieNode(key, args.Marshalizer, args.Hasher)
+	itn, err := trie.NewInterceptedTrieNode(serializedLeafNode, args.Hasher)
+	require.Nil(t, err)
+
+	args.TrieStorageManager = &testscommon.StorageManagerStub{
+		GetCalled: func(b []byte) ([]byte, error) {
+			return serializedLeafNode, nil
+		},
+	}
+
+	cacher := testscommon.NewCacherMock()
+	cacher.Put(key, itn, 0)
+	args.Cacher = cacher
+
+	v, err := syncer.NewValidatorAccountsSyncer(args)
+	require.Nil(t, err)
+
+	err = v.SyncAccounts(key)
+	require.Nil(t, err)
+}
+
+func TestValidatorAccountsSyncer_IsInterfaceNil(t *testing.T) {
+	t.Parallel()
+
+	var vas *syncer.ValidatorAccountsSyncer
+	assert.True(t, vas.IsInterfaceNil())
+
+	args := syncer.ArgsNewValidatorAccountsSyncer{
+		ArgsNewBaseAccountsSyncer: getDefaultBaseAccSyncerArgs(),
+	}
+	vas, err := syncer.NewValidatorAccountsSyncer(args)
+	require.Nil(t, err)
+	assert.False(t, vas.IsInterfaceNil())
+}