Back to Repositories

Testing ProcessExecutor Command Handling in Stirling-PDF

This test suite validates the ProcessExecutor utility class in Stirling-PDF, focusing on command execution and output handling. It verifies both successful command execution and error handling scenarios using JUnit testing framework.

Test Coverage Overview

The test suite provides comprehensive coverage of the ProcessExecutor functionality, focusing on command execution and output handling.

  • Tests successful command execution with Java version command
  • Validates error handling for non-existent commands
  • Verifies process exit codes and output message handling
  • Covers ProcessExecutor singleton instance initialization

Implementation Analysis

The testing approach utilizes JUnit 5’s modern features for robust unit testing.

Key implementation patterns include:
  • BeforeEach setup for ProcessExecutor initialization
  • Exception testing using assertThrows
  • Command list construction for process execution
  • Output validation through ProcessExecutorResult object

Technical Details

Testing infrastructure includes:
  • JUnit Jupiter test framework
  • Java IO for process execution
  • ProcessExecutor utility class
  • Custom ProcessExecutorResult class for output handling
  • System command execution simulation

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Proper test isolation through @BeforeEach setup
  • Explicit error case handling and validation
  • Clear test method naming conventions
  • Comprehensive assertion checks
  • Effective use of JUnit 5 assertions and exceptions testing

stirling-tools/stirling-pdf

src/test/java/stirling/software/SPDF/utils/ProcessExecutorTest.java

            
package stirling.software.SPDF.utils;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class ProcessExecutorTest {

    private ProcessExecutor processExecutor;

    @BeforeEach
    public void setUp() {
        // Initialize the ProcessExecutor instance
        processExecutor = ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE);
    }

    @Test
    public void testRunCommandWithOutputHandling() throws IOException, InterruptedException {
        // Mock the command to execute
        List<String> command = new ArrayList<>();
        command.add("java");
        command.add("-version");

        // Execute the command
        ProcessExecutor.ProcessExecutorResult result = processExecutor.runCommandWithOutputHandling(command);

        // Check the exit code and output messages
        assertEquals(0, result.getRc());
        assertNotNull(result.getMessages()); // Check if messages are not null
    }

    @Test
    public void testRunCommandWithOutputHandling_Error() {
        // Mock the command to execute
        List<String> command = new ArrayList<>();
        command.add("nonexistent-command");

        // Execute the command and expect an IOException
        IOException thrown = assertThrows(IOException.class, () -> {
            processExecutor.runCommandWithOutputHandling(command);
        });

        // Log the actual error message
        System.out.println("Caught IOException: " + thrown.getMessage());

        // Check the exception message to ensure it indicates the command was not found
        String errorMessage = thrown.getMessage();
        assertTrue(errorMessage.contains("error=2") || errorMessage.contains("No such file or directory"), "Unexpected error message: " + errorMessage);
    }
}