Skip to content

Testing Providers

PatternOps uses a multi-layered testing strategy for providers.

Test Layers

Layer Framework Purpose
Unit Tests JUnit 5 Individual method behaviour
Property Tests jqwik Correctness properties across random inputs
Contract Tests JUnit 5 Verify contract compliance
Integration Tests JUnit 5 + Testcontainers Real infrastructure

Unit Testing

Test individual provider methods with mocked dependencies:

@Test
void write_validKeyAndState_persists() {
    provider.write("key-1", Map.of("status", "RUNNING"));
    Object state = provider.read("key-1");
    assertThat(state).isEqualTo(Map.of("status", "RUNNING"));
}

@Test
void validateConfig_missingRequired_returnsViolations() {
    ValidationResult result = provider.validateConfig(Map.of());
    assertThat(result.valid()).isFalse();
    assertThat(result.violations()).isNotEmpty();
}

Property-Based Testing

Use jqwik to verify correctness properties:

@Property(tries = 200)
void writeReadRoundTrip(@ForAll("validKeys") String key, @ForAll("validStates") Object state) {
    provider.write(key, state);
    Object read = provider.read(key);
    assertThat(read).isEqualTo(state);
}

@Property(tries = 100)
void deleteRemovesState(@ForAll("validKeys") String key) {
    provider.write(key, "value");
    provider.delete(key);
    assertThat(provider.read(key)).isNull();
}

Contract Compliance Testing

Verify that a provider correctly implements all contract methods:

abstract class StateManagementContractTest {

    abstract StateManagementContract createProvider();

    @Test
    void implementsAllContractMethods() {
        StateManagementContract provider = createProvider();

        // Base contract
        assertDoesNotThrow(() -> provider.validateConfig(validConfig()));
        assertDoesNotThrow(() -> provider.initialise(validConfig()));
        assertDoesNotThrow(() -> provider.healthCheck());
        assertDoesNotThrow(() -> provider.metrics());
        assertDoesNotThrow(() -> provider.cleanup());
    }

    @Test
    void healthCheckAfterInitialise_returnsHealthy() {
        StateManagementContract provider = createProvider();
        provider.initialise(validConfig());
        assertThat(provider.healthCheck().status())
            .isEqualTo(HealthStatus.Status.HEALTHY);
    }
}

Running Tests

# All tests
mvn test

# Core module only
mvn test -pl core

# Specific test class
mvn test -pl core -Dtest=ConfigurationRoundTripProperties

# Property tests only (by naming convention)
mvn test -pl core -Dtest="*Properties"

Test Naming Conventions

Pattern Surefire Picks Up
*Test.java
*Tests.java
*Properties.java ✅ (jqwik property tests)