diff --git a/cli/src/main/java/dev/fitko/fitconnect/cli/CommandExecutor.java b/cli/src/main/java/dev/fitko/fitconnect/cli/CommandExecutor.java
index cd52dad9da02b71b64980ad4808fb99c62d7ed56..d6fc41b0b7b91b4050239e7d01b2f3b59541c1fe 100644
--- a/cli/src/main/java/dev/fitko/fitconnect/cli/CommandExecutor.java
+++ b/cli/src/main/java/dev/fitko/fitconnect/cli/CommandExecutor.java
@@ -1,6 +1,5 @@
 package dev.fitko.fitconnect.cli;
 
-import dev.fitko.fitconnect.api.config.ApplicationConfig;
 import dev.fitko.fitconnect.api.domain.model.submission.SentSubmission;
 import dev.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
 import dev.fitko.fitconnect.api.exceptions.internal.BatchImportException;
@@ -17,9 +16,8 @@ import dev.fitko.fitconnect.cli.keygen.JWKPair;
 import dev.fitko.fitconnect.cli.keygen.KeyWriter;
 import dev.fitko.fitconnect.cli.keygen.KeyWriterSettings;
 import dev.fitko.fitconnect.cli.util.AttachmentDataType;
+import dev.fitko.fitconnect.client.SenderClient;
 import dev.fitko.fitconnect.client.SubscriberClient;
-import dev.fitko.fitconnect.client.bootstrap.ApplicationConfigLoader;
-import dev.fitko.fitconnect.client.bootstrap.ClientFactory;
 import dev.fitko.fitconnect.client.sender.model.Attachment;
 import dev.fitko.fitconnect.client.sender.model.SendableSubmission;
 import dev.fitko.fitconnect.client.subscriber.ReceivedSubmission;
@@ -36,6 +34,7 @@ import java.nio.file.Path;
 import java.util.List;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -47,21 +46,22 @@ class CommandExecutor {
 
     private static final String IMPORTED_RECORD_TEMPLATE = "\n\n================== Imported record {} ==================\n";
 
-    private static final String DEFAULT_CONFIG_NAME = "config.yml";
-
     private final BatchImporter batchImporter;
     private final JWKGenerator jwkGenerator;
+    private final Supplier<SenderClient> senderSupplier;
+    private final Supplier<SubscriberClient> subscriberSupplier;
 
-    CommandExecutor(final BatchImporter batchImporter, final JWKGenerator jwkGenerator) {
+    CommandExecutor(final Supplier<SenderClient> senderSupplier, final Supplier<SubscriberClient> subscriberSupplier, final BatchImporter batchImporter, final JWKGenerator jwkGenerator) {
         this.batchImporter = batchImporter;
         this.jwkGenerator = jwkGenerator;
+        this.senderSupplier = senderSupplier;
+        this.subscriberSupplier = subscriberSupplier;
     }
 
     void getOneSubmission(final GetOneSubmissionCommand getOneSubmissionCommand) throws IOException {
-        final SubscriberClient subscriberClient = ClientFactory.getSubscriberClient(loadConfig());
         LOGGER.info("Getting submission for id {}", getOneSubmissionCommand.submissionId);
         final var startTime = StopWatch.start();
-        final var submission = subscriberClient.requestSubmission(getOneSubmissionCommand.submissionId);
+        final var submission = subscriberSupplier.get().requestSubmission(getOneSubmissionCommand.submissionId);
         LOGGER.info("Submission download took {}", StopWatch.stopWithFormattedTime(startTime));
         if (submission == null) {
             LOGGER.info("No submission found for submission id {}", getOneSubmissionCommand.submissionId);
@@ -72,10 +72,9 @@ class CommandExecutor {
     }
 
     void getAllSubmissions(final GetAllSubmissionsCommand getAllSubmissionsCommand) throws IOException {
-        final SubscriberClient subscriberClient = ClientFactory.getSubscriberClient(loadConfig());
         final var destinationId = getAllSubmissionsCommand.destinationId;
         LOGGER.info("Getting all available submissions for destination {}", destinationId);
-        final Set<SubmissionForPickup> submissions = subscriberClient.getAvailableSubmissionsForDestination(destinationId);
+        final Set<SubmissionForPickup> submissions = subscriberSupplier.get().getAvailableSubmissionsForDestination(destinationId);
         for (final SubmissionForPickup submission : submissions) {
             final GetOneSubmissionCommand getOneSubmissionCommand = new GetOneSubmissionCommand();
             getOneSubmissionCommand.submissionId = submission.getSubmissionId();
@@ -85,10 +84,9 @@ class CommandExecutor {
     }
 
     void listSubmissions(final ListAllSubmissionsCommand listAllSubmissionsCommand) {
-        final SubscriberClient subscriberClient = ClientFactory.getSubscriberClient(loadConfig());
         final var destinationId = listAllSubmissionsCommand.destinationId;
         LOGGER.info("Listing available submissions for destination {}", destinationId);
-        for (final SubmissionForPickup submission : subscriberClient.getAvailableSubmissionsForDestination(destinationId)) {
+        for (final SubmissionForPickup submission : subscriberSupplier.get().getAvailableSubmissionsForDestination(destinationId)) {
             LOGGER.info("caseId: {} - submissionId: {}", submission.getCaseId(), submission.getSubmissionId());
         }
     }
@@ -150,7 +148,7 @@ class CommandExecutor {
                 .addAttachments(attachments)
                 .build();
 
-        return ClientFactory.getSenderClient(loadConfig()).send(sendableSubmission);
+        return senderSupplier.get().send(sendableSubmission);
     }
 
     private SentSubmission sendWithXmlData(final SendSubmissionCommand sendSubmissionCommand, final List<Attachment> attachments) throws IOException {
@@ -162,7 +160,7 @@ class CommandExecutor {
                 .addAttachments(attachments)
                 .build();
 
-        return ClientFactory.getSenderClient(loadConfig()).send(sendableSubmission);
+        return senderSupplier.get().send(sendableSubmission);
     }
 
     private String getTargetFolderPath(final GetOneSubmissionCommand getOneSubmissionCommand) {
@@ -209,14 +207,4 @@ class CommandExecutor {
         submission.setAttachments(Stream.of(importRecord.getAttachments().split(",")).map(String::trim).collect(Collectors.toList()));
         return submission;
     }
-
-    private ApplicationConfig loadConfig() {
-        try {
-            return ApplicationConfigLoader.loadConfigFromEnvironment();
-        } catch (final Exception e) {
-            LOGGER.info("Loading config from default location {}", DEFAULT_CONFIG_NAME);
-            return ApplicationConfigLoader.loadConfigFromPath(Path.of(DEFAULT_CONFIG_NAME));
-        }
-    }
-
 }
diff --git a/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineClient.java b/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineClient.java
index 781ca4f315506940ccf6f125efd75530a7c243bb..1186083cae8f19981b882909ad8b664e213657ab 100644
--- a/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineClient.java
+++ b/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineClient.java
@@ -10,10 +10,13 @@ import dev.fitko.fitconnect.cli.commands.ListAllSubmissionsCommand;
 import dev.fitko.fitconnect.cli.commands.SendBatchCommand;
 import dev.fitko.fitconnect.cli.commands.SendSubmissionCommand;
 import dev.fitko.fitconnect.cli.keygen.JWKGenerator;
+import dev.fitko.fitconnect.client.SenderClient;
+import dev.fitko.fitconnect.client.SubscriberClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.function.Supplier;
 
 class CommandLineClient {
 
@@ -29,7 +32,7 @@ class CommandLineClient {
 
     private final JCommander jc;
 
-    CommandLineClient() {
+    CommandLineClient(final Supplier<SenderClient> senderSupplier, final Supplier<SubscriberClient> subscriberSupplier) {
 
         sendSubmissionCommand = new SendSubmissionCommand();
         listAllSubmissionsCommand = new ListAllSubmissionsCommand();
@@ -38,7 +41,7 @@ class CommandLineClient {
         sendBatchCommand = new SendBatchCommand();
         createTestKeysCommand = new CreateTestKeysCommand();
 
-        commandExecutor = new CommandExecutor(new CsvImporter(), new JWKGenerator());
+        commandExecutor = new CommandExecutor(senderSupplier, subscriberSupplier, new CsvImporter(), new JWKGenerator());
 
         jc = getJCommander();
     }
diff --git a/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineRunner.java b/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineRunner.java
index 81fa763696bca6bb1707d5697a531bcc8df30152..a8833206125d3861e7218dc92b068cbd6927e6b2 100644
--- a/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineRunner.java
+++ b/cli/src/main/java/dev/fitko/fitconnect/cli/CommandLineRunner.java
@@ -1,25 +1,48 @@
 package dev.fitko.fitconnect.cli;
 
+import dev.fitko.fitconnect.api.config.ApplicationConfig;
+import dev.fitko.fitconnect.client.SenderClient;
+import dev.fitko.fitconnect.client.SubscriberClient;
+import dev.fitko.fitconnect.client.bootstrap.ApplicationConfigLoader;
+import dev.fitko.fitconnect.client.bootstrap.ClientFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.nio.file.Path;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 public final class CommandLineRunner {
-
+    private static final Logger LOGGER = LoggerFactory.getLogger(CommandLineRunner.class);
     private static final String LOGO = "/splash_screen_banner.txt";
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(CommandLineRunner.class);
+    private static final String DEFAULT_CONFIG_NAME = "config.yml";
+
 
     private CommandLineRunner() {
     }
 
     public static void main(final String[] args) {
         printSplashScreen();
-        new CommandLineClient().run(args);
+        getCommandLineClient().run(args);
+    }
+
+    private static CommandLineClient getCommandLineClient() {
+        final Supplier<SenderClient> senderClientSupplier = () -> ClientFactory.getSenderClient(loadConfig());
+        final Supplier<SubscriberClient> subscriberClientSupplier = () -> ClientFactory.getSubscriberClient(loadConfig());
+        return new CommandLineClient(senderClientSupplier, subscriberClientSupplier);
+    }
+
+    private static ApplicationConfig loadConfig() {
+        try {
+            return ApplicationConfigLoader.loadConfigFromEnvironment();
+        } catch (final Exception e) {
+            LOGGER.info("Loading config from default location {}", DEFAULT_CONFIG_NAME);
+            return ApplicationConfigLoader.loadConfigFromPath(Path.of(DEFAULT_CONFIG_NAME));
+        }
     }
 
     private static void printSplashScreen() {
diff --git a/cli/src/test/java/dev/fitko/fitconnect/cli/CommandLineClientTest.java b/cli/src/test/java/dev/fitko/fitconnect/cli/CommandLineClientTest.java
index 087c364cee1686017ce827466364b8b2c3f39b3a..07c7c57b4da11e465dfd2d6e03d503ff5b4a4e54 100644
--- a/cli/src/test/java/dev/fitko/fitconnect/cli/CommandLineClientTest.java
+++ b/cli/src/test/java/dev/fitko/fitconnect/cli/CommandLineClientTest.java
@@ -44,7 +44,7 @@ class CommandLineClientTest {
         senderClientMock = mock(SenderClient.class);
         subscriberMock = mock(Subscriber.class);
         subscriberClientMock = mock(SubscriberClient.class);
-        underTest = new CommandLineClient();
+        underTest = new CommandLineClient(() -> senderClientMock, () -> subscriberClientMock);
     }
 
     @Test
@@ -126,7 +126,6 @@ class CommandLineClientTest {
     void testBatchImport() {
 
         // Given
-
         final var testDataPath = "src/test/resources/batch_data.csv";
         final List<ImportRecord> importRecords = new CsvImporter().readRecords(testDataPath);