diff --git a/testing-modules/junit-5-basics-2/README.md b/testing-modules/junit-5-basics-2/README.md
new file mode 100644
index 0000000000..f5e2558332
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Test Main Method with JUnit](http://www.baeldung.com/junit-5)
diff --git a/testing-modules/junit-5-basics-2/pom.xml b/testing-modules/junit-5-basics-2/pom.xml
new file mode 100644
index 0000000000..5e9786b315
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+ junit-5-basics-2
+
+
+
+
+ commons-cli
+ commons-cli
+ ${commons-cli.version}
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter-api.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito-core.version}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 11
+ 11
+
+
+
+
+
+
+ 11
+ 11
+ UTF-8
+ 1.5.0
+ 5.10.0
+ 5.4.0
+
+
+
\ No newline at end of file
diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Bootstrapper.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Bootstrapper.java
new file mode 100644
index 0000000000..1863342431
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Bootstrapper.java
@@ -0,0 +1,63 @@
+package com.baeldung.junit.main.test;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+public class Bootstrapper {
+ private final InputReader inputReader;
+ private final Calculator calculator;
+
+ public Bootstrapper(InputReader inputReader, Calculator calculator) {
+ this.inputReader = inputReader;
+ this.calculator = calculator;
+ }
+
+ public void processRequest(String[] args) {
+ try {
+ Options options = getOptions();
+ CommandLineParser parser = new DefaultParser();
+ CommandLine commandLine = parser.parse(options, args);
+
+ if (commandLine.hasOption("i")) {
+ System.out.print("Option i is present. The value is: " + commandLine.getOptionValue("i") + " \n");
+ String optionValue = commandLine.getOptionValue("i");
+ InputType inputType = InputType.valueOf(optionValue);
+
+ String fileName = null;
+ if (commandLine.hasOption("f")) {
+ fileName = commandLine.getOptionValue("f");
+ }
+ String inputString = inputReader.read(inputType, fileName);
+ int calculatedSum = calculator.calculateSum(inputString);
+ }
+
+ } catch (ParseException exception) {
+ System.out.print("Parse error: " + exception.getMessage());
+ }
+ }
+
+ public static Options getOptions() {
+ Option fileNameOption = Option.builder("f")
+ .required(false)
+ .desc("The file name option")
+ .type(String.class)
+ .build();
+ Option inputTypeOption = Option.builder("i")
+ .longOpt("input")
+ .required(true)
+ .desc("The input type")
+ .type(InputType.class)
+ .hasArg()
+ .build();
+
+ Options options = new Options();
+
+ options.addOption(inputTypeOption);
+ options.addOption(fileNameOption);
+ return options;
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Calculator.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Calculator.java
new file mode 100644
index 0000000000..a741a0b03a
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Calculator.java
@@ -0,0 +1,17 @@
+package com.baeldung.junit.main.test;
+
+import java.util.Arrays;
+
+public class Calculator {
+
+ public int calculateSum(String input) {
+ String[] array = input.split(" ");
+ int sum = Arrays.stream(array)
+ .map(Integer::valueOf)
+ .mapToInt(Integer::intValue)
+ .sum();
+ System.out.println("Calculated sum: " + sum);
+ return sum;
+ }
+
+}
\ No newline at end of file
diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputReader.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputReader.java
new file mode 100644
index 0000000000..d26c878e22
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputReader.java
@@ -0,0 +1,40 @@
+package com.baeldung.junit.main.test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Scanner;
+
+public class InputReader {
+
+ public String read(InputType inputType, String fileName) {
+ switch (inputType) {
+ case FILE:
+ return readFromFile(fileName);
+ case CONSOLE:
+ return readFromConsole();
+ default:
+ return null;
+ }
+ }
+
+ private String readFromConsole() {
+ System.out.println("Enter values for calculation: \n");
+ String str = new Scanner(System.in).nextLine();
+
+ return str;
+ }
+
+ private String readFromFile(String fileName) {
+ String readString = null;
+ try {
+ readString = Files.readString(Path.of(URI.create(fileName)));
+ System.out.println(readString);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputType.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputType.java
new file mode 100644
index 0000000000..fbf26b7df3
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputType.java
@@ -0,0 +1,5 @@
+package com.baeldung.junit.main.test;
+
+public enum InputType {
+ FILE, CONSOLE
+}
diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/SimpleMain.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/SimpleMain.java
new file mode 100644
index 0000000000..346162bbae
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/SimpleMain.java
@@ -0,0 +1,16 @@
+package com.baeldung.junit.main.test;
+
+import java.util.Arrays;
+
+public class SimpleMain {
+
+ public static void main(String[] args) {
+
+ System.out.println("Received input parameters: " + Arrays.asList(args));
+
+ Bootstrapper bootstrapper = new Bootstrapper(new InputReader(), new Calculator());
+
+ bootstrapper.processRequest(args);
+ }
+
+}
\ No newline at end of file
diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/StaticMain.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/StaticMain.java
new file mode 100644
index 0000000000..8c14bfd973
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/StaticMain.java
@@ -0,0 +1,118 @@
+package com.baeldung.junit.main.test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Scanner;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+public class StaticMain {
+
+ public static void main(String[] args) {
+
+ System.out.println("Received input parameters: " + Arrays.asList(args));
+
+ processRequest(args);
+ }
+
+ public static void processRequest(String[] args) {
+ try {
+ Options options = getOptions();
+ CommandLineParser parser = new DefaultParser();
+ CommandLine commandLine = parser.parse(options, args);
+
+ if (commandLine.hasOption("V")) {
+ System.out.print("Option V is present. The value is: ");
+ System.out.println(commandLine.getOptionValue("V"));
+ }
+
+ if (commandLine.hasOption("i")) {
+ System.out.print("Option i is present. The value is: " + commandLine.getOptionValue("i") + " \n");
+ String optionValue = commandLine.getOptionValue("i");
+ InputType inputType = InputType.valueOf(optionValue);
+
+ String fileName = null;
+ if (commandLine.hasOption("f")) {
+ fileName = commandLine.getOptionValue("f");
+ }
+ String inputString = read(inputType, fileName);
+ int calculatedSum = calculateSum(inputString);
+ }
+
+ } catch (ParseException exception) {
+ System.out.print("Parse error: ");
+ System.out.println(exception.getMessage());
+ }
+ }
+
+ public static Options getOptions() {
+
+ Option inputTypeOption = Option.builder("i")
+ .longOpt("input")
+ .required(true)
+ .desc("The input type")
+ .type(InputType.class)
+ .hasArg()
+ .build();
+ Option fileNameOption = Option.builder("f")
+ .required(false)
+ .desc("The file name option")
+ .type(String.class)
+ .hasArg()
+ .build();
+
+ Options options = new Options();
+
+ options.addOption(inputTypeOption);
+ options.addOption(fileNameOption);
+ return options;
+ }
+
+ public static int calculateSum(String input) {
+ if (input == null) {
+ return 0;
+ }
+ String[] array = input.split(" ");
+ int sum = Arrays.stream(array)
+ .map(Integer::valueOf)
+ .mapToInt(Integer::intValue)
+ .sum();
+ System.out.println("Calculated sum: " + sum);
+ return sum;
+ }
+
+ private static String readFromConsole() {
+ System.out.println("Enter values for calculation: \n");
+ return new Scanner(System.in).nextLine();
+ }
+
+ private static String readFromFile(String fileName) {
+ String readString = null;
+ try {
+ readString = Files.readString(Path.of(URI.create(fileName)));
+ System.out.println(readString);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+
+ public static String read(InputType inputType, String fileName) {
+ switch (inputType) {
+ case FILE:
+ return readFromFile(fileName);
+ case CONSOLE:
+ return readFromConsole();
+ default:
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestSimpleMain.java b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestSimpleMain.java
new file mode 100644
index 0000000000..90c9a0bba0
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestSimpleMain.java
@@ -0,0 +1,100 @@
+package com.baeldung.junit.main.test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class TestSimpleMain {
+ private InputStream defaultIn;
+ private PrintStream defaultOut;
+
+ @BeforeEach
+ public void setUp() {
+ defaultIn = System.in;
+ defaultOut = System.out;
+ }
+
+ @AfterEach
+ public void tearDown() {
+ System.setIn(defaultIn);
+ System.setOut(defaultOut);
+ }
+
+ @Test
+ public void givenArgumentAsConsoleInput_WhenReadFromSubstitutedByteStream_ThenSuccessfullyCalculate() throws IOException {
+ String[] arguments = new String[] { "-i", "CONSOLE" };
+
+ final InputStream fips = new ByteArrayInputStream("1 2 3".getBytes());
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ final PrintStream out = new PrintStream(byteArrayOutputStream);
+
+ System.setIn(fips);
+ System.setOut(out);
+
+ //execute
+ SimpleMain.main(arguments);
+
+ //verify
+ String consoleOutput = byteArrayOutputStream.toString(Charset.defaultCharset());
+ assertTrue(consoleOutput.contains("Calculated sum: 6"));
+
+ fips.close();
+ out.close();
+ }
+
+ @Test
+ public void givenArgumentAsConsoleInput_WhenReadFromSubstitutedFileStream_ThenSuccessfullyCalculate() throws IOException {
+ String[] arguments = new String[] { "-i", "CONSOLE" };
+
+ final InputStream fips = getClass().getClassLoader()
+ .getResourceAsStream("test-input.txt");
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ final PrintStream out = new PrintStream(byteArrayOutputStream);
+
+ System.setIn(fips);
+ System.setOut(out);
+
+ //execute
+ SimpleMain.main(arguments);
+
+ //verify
+ String consoleOutput = byteArrayOutputStream.toString(Charset.defaultCharset());
+ assertTrue(consoleOutput.contains("Calculated sum: 10"));
+
+ fips.close();
+ out.close();
+ }
+
+ @Test
+ public void givenLongArgumentAsConsoleInput_WhenReadFromSubstitutedFileStream_ThenSuccessfullyCalculate() throws IOException {
+ String[] arguments = new String[] { "--input", "CONSOLE" };
+
+ final InputStream fips = getClass().getClassLoader()
+ .getResourceAsStream("test-input.txt");
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ final PrintStream out = new PrintStream(byteArrayOutputStream);
+
+ System.setIn(fips);
+ System.setOut(out);
+
+ //execute
+ SimpleMain.main(arguments);
+
+ //verify
+ String consoleOutput = byteArrayOutputStream.toString(Charset.defaultCharset());
+ assertTrue(consoleOutput.contains("Calculated sum: 10"));
+
+ fips.close();
+ out.close();
+ }
+
+}
diff --git a/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestStaticMain.java b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestStaticMain.java
new file mode 100644
index 0000000000..0c81a0cbbc
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestStaticMain.java
@@ -0,0 +1,37 @@
+package com.baeldung.junit.main.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+public class TestStaticMain {
+
+ @Test
+ public void givenArgumentAsConsoleInput_WhenReadFromSubstitutedByteArrayInputStream_ThenSuccessfullyCalculate() throws IOException {
+ String[] arguments = new String[] { "-i", "CONSOLE" };
+ try (MockedStatic mockedStatic = Mockito.mockStatic(StaticMain.class, Mockito.CALLS_REAL_METHODS);
+ InputStream fips = new ByteArrayInputStream("1 2 3".getBytes())) {
+
+ final InputStream original = System.in;
+
+ //Reassigns the "standard" input stream
+ System.setIn(fips);
+
+ ArgumentCaptor stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
+
+ //execute
+ StaticMain.main(arguments);
+
+ //verify
+ mockedStatic.verify(() -> StaticMain.calculateSum(stringArgumentCaptor.capture()));
+
+ System.setIn(original);
+ }
+ }
+
+}
diff --git a/testing-modules/junit-5-basics-2/src/test/resources/test-input.txt b/testing-modules/junit-5-basics-2/src/test/resources/test-input.txt
new file mode 100644
index 0000000000..6163c9426b
--- /dev/null
+++ b/testing-modules/junit-5-basics-2/src/test/resources/test-input.txt
@@ -0,0 +1 @@
+4 5 1
\ No newline at end of file
diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml
index 108ce29b86..fa72b1e696 100644
--- a/testing-modules/pom.xml
+++ b/testing-modules/pom.xml
@@ -27,6 +27,7 @@
junit-4
junit-5-advanced
junit-5-basics
+ junit-5-basics-2
junit-5
junit5-annotations
junit5-migration