Class Swappers

java.lang.Object
org.apache.juneau.junit.bct.Swappers

public class Swappers extends Object
Collection of standard swapper implementations for the Bean-Centric Testing framework.

This class provides built-in object transformation strategies that handle common wrapper types and asynchronous objects. These swappers are automatically registered when using BasicBeanConverter.Builder.defaultSettings().

Purpose:

Swappers pre-process objects before stringification or listification, enabling the converter to handle wrapper types, lazy evaluation objects, and asynchronous results consistently. They transform objects into more primitive forms that can be easily converted to strings or lists.

Built-in Swappers:
Usage Example:

// Register swappers using builder var converter = BasicBeanConverter.builder() .defaultSettings() .addSwapper(Optional.class, Swappers.optionalSwapper()) .addSwapper(Supplier.class, Swappers.supplierSwapper()) .addSwapper(Future.class, Swappers.futureSwapper()) .build();

Custom Swapper Development:

When creating custom swappers, follow these patterns:

  • Null Safety: Handle null inputs gracefully
  • Exception Handling: Convert exceptions to meaningful error messages
  • Status Indication: Provide clear status for incomplete or error states
  • Non-blocking: Avoid blocking operations that might hang tests
  • Recursion Prevention: Ensure swappers don't create circular transformations that could lead to StackOverflowError. The framework does not check for recursion, so developers must avoid registering swappers that transform objects back to types that would trigger the same or other swappers in an endless cycle.
See Also:
  • Method Details

    • optionalSwapper

      public static Swapper<Optional> optionalSwapper()
      Returns a swapper for Optional objects that unwraps them to their contained values.

      This swapper extracts the value from Optional instances, returning the contained object if present, or null if the Optional is empty. This allows Optional-wrapped values to be processed naturally by the converter without special handling.

      Behavior:
      • Present value: Returns the contained object for further processing
      • Empty Optional: Returns null, which will be rendered as the configured null value
      Usage Examples:

      // Test Optional with value var optional = Optional.of("Hello"); assertBean(optional, "<self>", "Hello"); // Test empty Optional var empty = Optional.empty(); assertBean(empty, "<self>", "<null>"); // Test nested Optional in object var user = new User().setName(Optional.of("John")); assertBean(user, "name", "John");

      Integration:

      This swapper is particularly useful when working with modern Java APIs that return Optional values. It allows test assertions to focus on the actual data rather than Optional wrapper mechanics.

      Returns:
      A Swapper for Optional objects
      See Also:
    • supplierSwapper

      public static Swapper<Supplier> supplierSwapper()
      Returns a swapper for Supplier objects that evaluates them to get their supplied values.

      This swapper calls the Supplier.get() method to obtain the value that the supplier provides. This enables testing of lazy-evaluated or dynamically-computed values as if they were regular objects.

      Behavior:
      • Successful evaluation: Returns the result of calling Supplier.get()
      • Exception during evaluation: Allows the exception to propagate (no special handling)
      Usage Examples:

      // Test supplier with simple value var supplier = () -> "Hello World"; assertBean(supplier, "<self>", "Hello World"); // Test supplier in object property var config = new Configuration().setDynamicValue(() -> calculateValue()); assertBean(config, "dynamicValue", "computed-result"); // Test supplier returning null var nullSupplier = () -> null; assertBean(nullSupplier, "<self>", "<null>");

      Important Notes:
      • Side Effects: The supplier will be evaluated during conversion, which may cause side effects
      • Performance: Expensive computations in suppliers will impact test performance
      • Exception Handling: Exceptions from suppliers are not caught by this swapper
      Returns:
      A Swapper for Supplier objects
      See Also:
    • futureSwapper

      public static Swapper<Future> futureSwapper()
      Returns a swapper for Future objects that extracts completed results or status information.

      This swapper handles Future objects in a non-blocking manner, providing meaningful information about the future's state without waiting for completion:

      Behavior:
      • Completed successfully: Returns the actual result value
      • Completed with exception: Returns "<error: {message}>" format
      • Cancelled: Returns "<cancelled>"
      • Still pending: Returns "<pending>"
      Usage Examples:

      // Test completed future var future = CompletableFuture.completedFuture("Hello"); assertBean(future, "<self>", "Hello"); // Test pending future var pending = new CompletableFuture<String>(); assertBean(pending, "<self>", "<pending>"); // Test cancelled future var cancelled = new CompletableFuture<String>(); cancelled.cancel(true); assertBean(cancelled, "<self>", "<cancelled>"); // Test failed future var failed = new CompletableFuture<String>(); failed.completeExceptionally(new RuntimeException("Test error")); assertBean(failed, "<self>", "<error: Test error>");

      Non-blocking Guarantee:

      This swapper never calls Future.get() without first checking Future.isDone(), ensuring that test execution is never blocked by incomplete futures. This makes it safe to use in unit tests without risking hangs or timeouts.

      Error Handling:

      When a future completes exceptionally, the swapper extracts the exception message and formats it as "<error: {message}>". This provides useful debugging information while maintaining a consistent string format for assertions.

      Returns:
      A Swapper for Future objects
      See Also: