Testing
June 24, 2026 · View on GitHub
Overview
MockServer uses a multi-layered testing strategy spanning unit tests, integration tests, packaging verification tests, container integration tests, and performance tests. Tests are predominantly written in JUnit 4 with a small number of JUnit 5 tests in the mockserver-junit-jupiter module.
graph TB
subgraph "Unit Tests (Surefire)"
UT["*Test.java — ~251 files"]
end
subgraph "Integration Tests (Failsafe)"
IT["*IntegrationTest.java — ~184 files"]
end
subgraph "Packaging Integration Tests"
MI["Maven Invoker — 3 sub-builds"]
GI["Gradle — 2 sub-builds"]
end
subgraph "Container Integration Tests"
DC["Docker Compose — 16 tests"]
HT["Helm/k3d — 8 tests"]
end
subgraph "Performance Tests"
PT["k6"]
end
UT --> IT --> MI & GI --> DC & HT --> PT
Test Frameworks and Dependencies
| Framework | Version | Usage |
|---|---|---|
| JUnit 4 | 4.13.2 | Primary test framework across almost all modules |
| JUnit Jupiter (JUnit 5) | 5.14.4 | Used exclusively in mockserver-junit-jupiter |
| Mockito Core | 5.23.0 | Mocking framework used in most modules |
| Mockito JUnit Jupiter | 5.23.0 | JUnit 5 Mockito integration (mockserver-junit-jupiter only) |
| Hamcrest | 3.0 | Assertion matchers used across all modules |
| JSONAssert | 1.5.3 | JSON assertion library (mockserver-core) |
| Spring Test | 5.3.39 | mockserver-core, mockserver-war, mockserver-proxy-war, mockserver-spring-test-listener, mockserver-examples |
| XMLUnit | 2.11.0 | XML comparison (production dependency, also supports test assertions) |
No TestNG is used anywhere in the project.
Test Inventory by Module
| Module | Unit Tests | Integration Tests | Total Test Files | Description |
|---|---|---|---|---|
mockserver-core | ~220 | ~62 | ~282 | Largest suite: matchers, serialization, validators, actions, collections, auth, logging |
mockserver-netty | ~13 | ~64 | ~77 | Server lifecycle, TLS, proxy, CORS, authenticated control plane |
mockserver-examples | 0 | ~25 | ~25 | End-to-end examples with various HTTP clients |
mockserver-junit-jupiter | ~6 | ~12 | ~18 | JUnit 5 extension tests (injection, parallel safety, settings) |
mockserver-junit-rule | ~4 | ~4 | ~8 | JUnit 4 Rule/ClassRule tests |
mockserver-war | 0 | ~8 | ~8 | WAR deployment integration tests (embedded Tomcat) |
mockserver-client-java | ~5 | ~2 | ~7 | Client API unit tests, event bus, serialization |
mockserver-spring-test-listener | ~2 | ~4 | ~6 | Spring TestExecutionListener tests |
mockserver-proxy-war | 0 | ~3 | ~3 | Proxy WAR integration tests (embedded Tomcat) |
mockserver-testing | 1 | 0 | 1 | Self-test for the Assert utility class |
mockserver-integration-testing | 0 | 0 | 0 | No tests of its own — it IS the shared test infrastructure |
| Total | ~251 | ~184 | ~435 |
Test Architecture
Naming Convention
Test filtering is done entirely by naming convention — no @Category or @Tag annotations are used:
| Pattern | Runner | Maven Phase | Plugin |
|---|---|---|---|
**/*Test.java | Surefire | test | maven-surefire-plugin 3.5.6 |
**/*IntegrationTest.java | Failsafe | integration-test / verify | maven-failsafe-plugin 3.5.6 |
Abstract Base Class Hierarchy
The project uses a template method pattern for integration tests. Abstract base classes in mockserver-integration-testing define hundreds of test cases, and concrete classes in each module provide the server wiring.
classDiagram
class AbstractMockingIntegrationTestBase {
<<abstract>>
#MockServerClient mockServerClient
#EchoServer insecureEchoServer
#EchoServer secureEchoServer
#NettyHttpClient httpClient
+beforeClass()
+afterClass()
}
class AbstractBasicMockingIntegrationTest {
<<abstract>>
+shouldReturnResponseByMatchingPath()
+shouldReturnResponseByMatchingMethod()
...~50 test methods
}
class AbstractExtendedMockingIntegrationTest {
<<abstract>>
+shouldForwardRequestInHTTPS()
+shouldCallbackToSpecifiedClass()
...~123 test methods
}
class AbstractExtendedSameJVMMockingIntegrationTest {
<<abstract>>
+shouldCallbackToSpecifiedObject()
...same-JVM callback tests
}
class AbstractProxyIntegrationTest {
<<abstract>>
+shouldForwardRequestsUsingSocketDirectly()
...proxy test methods
}
AbstractMockingIntegrationTestBase <|-- AbstractBasicMockingIntegrationTest
AbstractBasicMockingIntegrationTest <|-- AbstractBasicMockingSameJVMIntegrationTest
AbstractBasicMockingSameJVMIntegrationTest <|-- AbstractExtendedMockingIntegrationTest
AbstractExtendedMockingIntegrationTest <|-- AbstractExtendedSameJVMMockingIntegrationTest
AbstractMockingIntegrationTestBase <|-- AbstractProxyIntegrationTest
class AbstractBasicMockingSameJVMIntegrationTest {
<<abstract>>
Basic tests for same-JVM scenarios
}
class ClientAndServerMockingIntegrationTest {
+startServer()
Concrete: starts Netty server
}
class AbstractExtendedDeployableWARMockingIntegrationTest {
<<abstract>>
Intermediate: WAR deployment setup
}
class ExtendedWARMockingIntegrationTest {
+startServer()
Concrete: deploys to embedded Tomcat
}
class JUnitClassRuleIntegrationTest {
+startServer()
Concrete: uses JUnit 4 ClassRule
}
AbstractBasicMockingSameJVMIntegrationTest <|-- ClientAndServerMockingIntegrationTest
AbstractExtendedSameJVMMockingIntegrationTest <|-- AbstractExtendedDeployableWARMockingIntegrationTest
AbstractExtendedDeployableWARMockingIntegrationTest <|-- ExtendedWARMockingIntegrationTest
AbstractBasicMockingSameJVMIntegrationTest <|-- JUnitClassRuleIntegrationTest
This architecture means a single abstract test class change can affect tests across multiple modules. The mockserver-integration-testing module has no tests of its own — it exists solely to provide these shared base classes.
Assertion Patterns
Many tests use private helper methods or abstract base classes for assertions. Assertions are present but not always visible in the @Test method body. For example:
AuthenticatedControlPlaneUsing*IntegrationTestclasses delegate assertions toclientOperationIsAuthenticated()(usesassertThrows+assertThat) andhttpAPIOperationIsAuthenticated()(asserts HTTP 401 + error message)ConcurrencyBasicResponseMockingIntegrationTestruns assertions inside scheduled tasks viasendRequestAndVerifyResponse()which callsAssert.assertEqualsNettyHttpProxySOCKSIntegrationTestdelegates to helpers likeproxyRequestsUsingSocketViaSOCKS5()containing multiple assertions
Precanned Callbacks
The mockserver-integration-testing module provides precanned callback implementations in org.mockserver.testing.integration.callback:
| Class | Purpose |
|---|---|
PrecannedTestExpectationForwardCallbackRequest | Forward callback with request override |
PrecannedTestExpectationForwardCallbackRequestAndResponse | Forward callback with request and response override |
PrecannedTestExpectationResponseCallback | Response callback returning precanned response |
Unit Tests
Unit tests use JUnit 4 (or JUnit 5 in mockserver-junit-jupiter) and run via the Maven Surefire plugin during the test phase.
| Property | Value |
|---|---|
| Naming convention | *Test.java |
| Excludes | *IntegrationTest.java |
| Maven phase | test |
| Plugin | maven-surefire-plugin 3.5.6 |
| Log level | mockserver.logLevel=${mockserver.testLogLevel} (default: ERROR) |
| Locale | en-GB (-Duser.language=en -Duser.country=GB) |
| Test listener | org.mockserver.test.PrintOutCurrentTestRunListener |
| XML reports | Controlled by ${disableXmlReport} (default: true) |
| Forked process timeout | 1800 seconds |
| Fork count | Default (1 fork per module; forkCount=0 commented out for debugging) |
Running Unit Tests
./mvnw test
./mvnw test -pl mockserver-core
./mvnw test -pl mockserver-netty -Dtest=MockServerRuleTest
Integration Tests
Integration tests use JUnit 4 and run via the Maven Failsafe plugin during the integration-test and verify phases. They start real servers (Netty, embedded Tomcat) and exercise full request/response flows.
| Property | Value |
|---|---|
| Naming convention | *IntegrationTest.java |
| Maven phase | integration-test / verify |
| Plugin | maven-failsafe-plugin 3.5.6 |
| Log level | mockserver.logLevel=${mockserver.testLogLevel} (default: ERROR) |
| Extra system properties | project.version, project.basedir |
| Locale | en-GB |
| Test listener | org.mockserver.test.PrintOutCurrentTestRunListener |
| XML reports | Controlled by ${disableXmlReport} (default: true) |
| Forked process timeout | 1800 seconds |
Running Integration Tests
./mvnw verify
./mvnw verify -pl mockserver-netty
Integration Test Infrastructure
The mockserver-integration-testing module provides shared abstract test base classes:
| Class | Purpose |
|---|---|
AbstractMockingIntegrationTestBase | Base class with common setup/teardown (MockServerClient, EchoServer, NettyHttpClient) |
AbstractBasicMockingIntegrationTest | Basic mocking test cases (~50 methods) |
AbstractExtendedMockingIntegrationTest | Extended mocking with all action types (~123 methods) |
AbstractExtendedSameJVMMockingIntegrationTest | Same-JVM callback testing |
AbstractBasicMockingSameJVMIntegrationTest | Basic tests for same-JVM scenarios |
AbstractProxyIntegrationTest | Proxy mode integration tests |
Embedded Server Infrastructure
Integration tests use real embedded servers rather than mocks:
| Server | Module | Purpose |
|---|---|---|
EchoServer (Netty) | mockserver-core | Returns request details as response body (secure + insecure instances) |
| Embedded Tomcat 9.0.x | mockserver-war, mockserver-proxy-war | WAR deployment testing |
| MockServer (Netty) | mockserver-netty | Full server lifecycle testing |
Downstream Dependency Integration Tests
mockserver/mockserver-netty/src/integration-tests/ contains Maven Invoker and Gradle-based tests that verify the published mockserver-netty artifacts work correctly when consumed by a downstream project:
| Directory | Purpose |
|---|---|
maven-netty-jar-with-dependencies-dependency/ | Tests the :jar-with-dependencies classifier as a Maven dependency |
maven-netty-no-dependencies-dependency/ | Tests mockserver-netty-no-dependencies as a Maven dependency |
gradle-netty-no-dependencies-dependencies/ | Tests mockserver-netty-no-dependencies from Gradle |
These are run by maven-invoker-plugin (Maven variants, parallelThreads=2) and exec-maven-plugin calling gradle_integration_tests.sh (Gradle variant) during the integration-test/install phases. The legacy maven-netty-shaded-dependency and gradle-netty-shaded-dependencies directories were removed in 6.0.0 along with the <classifier>shaded</classifier> artifact form.
Container Integration Tests
Located in container_integration_tests/, these tests verify MockServer behaviour when running as a Docker container or Kubernetes pod. These are NOT run in CI — they are only invoked by local_quick_build.sh and local_online_build.sh. Estimated runtime is ~5-10 minutes (with pre-built JAR).
Running Container Integration Tests
container_integration_tests/integration_tests.sh
SKIP_HELM_TESTS=true container_integration_tests/integration_tests.sh
SKIP_JAVA_BUILD=true SKIP_DOCKER_BUILD_MOCKSERVER=true container_integration_tests/integration_tests.sh
Environment Variable Controls
| Variable | Default | Purpose |
|---|---|---|
SKIP_JAVA_BUILD | unset | Skip mvnw package step |
SKIP_DOCKER_BUILD_MOCKSERVER | unset | Skip building MockServer Docker image |
SKIP_DOCKER_REBUILD_CLIENT | unset | Skip rebuilding the curl client image |
SKIP_ALL_TESTS | unset | Skip all tests (build only) |
SKIP_DOCKER_TESTS | unset | Skip Docker Compose tests |
SKIP_HELM_TESTS | unset | Skip Helm/k3d tests |
Docker Compose Tests (16)
Each test has its own directory containing a docker-compose.yml and integration_test.sh:
| Test | Validates |
|---|---|
docker_compose_forward_with_override | Forward with request/response override |
docker_compose_remote_host_and_port_by_environment_variable | Remote host/port via MOCKSERVER_PROXY_REMOTE_HOST/PORT |
docker_compose_server_port_by_command | Server port via command-line argument |
docker_compose_server_port_by_environment_variable_long_name | Server port via MOCKSERVER_SERVER_PORT |
docker_compose_server_port_by_environment_variable_short_name | Server port via SERVER_PORT |
docker_compose_without_server_port | Default port (1080) |
docker_compose_with_expectation_initialiser | Expectation initialiser class |
docker_compose_with_persisted_expectations | Persisted expectations file |
docker_compose_with_server_port_from_default_properties_file | Port from mockserver.properties |
docker_compose_with_server_port_from_custom_properties_file | Port from custom properties file |
docker_compose_with_mtls | Mutual TLS (mTLS) client certificate verification |
docker_compose_jvm_options | Custom JVM options via JAVA_OPTS |
docker_compose_libs_classpath | Additional JARs on the /libs classpath |
docker_compose_graceful_shutdown | Graceful shutdown on SIGTERM |
docker_compose_metrics | Prometheus metrics endpoint |
docker_compose_war_tomcat | WAR deployment on Tomcat |
Helm Tests (8)
Helm tests use k3d (k3s in Docker) to create a local cluster:
| Test | Validates |
|---|---|
helm_default_config | Default Helm chart values |
helm_local_docker_container | Local Docker image loaded into k3d |
helm_custom_server_port | Custom server port via Helm values |
helm_remote_host_and_port | Remote host/port via Helm values |
helm_inline_config | Inline config via Helm values (app.config.enabled, app.config.initializerJson) |
helm_configmap_injection | External config via ConfigMap |
helm_mockserver_config_chart | Standalone MockServer config Helm chart |
helm_clustered_convergence | Clustered state convergence (Infinispan, non-blocking) |
Helper Scripts
| Script | Purpose |
|---|---|
integration_tests.sh | Main orchestrator: builds Docker image, runs all tests, prints summary |
docker-compose.sh | Docker Compose helper functions (start-up, tear-down, docker-exec, container-logs) |
helm-deploy.sh | k3d cluster lifecycle (start-up-k8s, tear-down-k8s), Helm install/uninstall |
logging.sh | Coloured terminal output, runCommand, retryCommand, logTestResult |
Test Flow
sequenceDiagram
participant R as integration_tests.sh
participant D as Docker
participant T as integration_test.sh
R->>R: Source logging.sh, helm-deploy.sh, docker-compose.sh
R->>D: Build MockServer image (mockserver/mockserver:integration_testing)
R->>D: Build curl client image
loop For each Docker Compose test
R->>T: cd test_dir && ./integration_test.sh
T->>D: docker-compose -p $TEST_CASE up -d
T->>D: docker-exec client "curl ..." (create expectation)
T->>D: docker-exec client "curl ..." (verify behaviour)
T->>R: logTestResult $? $TEST_CASE
T->>D: docker-compose -p $TEST_CASE down
end
R->>R: Start k3d cluster
loop For each Helm test
R->>T: cd test_dir && ./integration_test.sh
T->>D: helm install ... && kubectl wait ...
T->>D: kubectl exec client -- curl ...
T->>R: logTestResult $? $TEST_CASE
T->>D: helm uninstall
end
R->>R: Tear down k3d cluster
R->>R: Print PASSED/FAILED summary
Docker Image Variant Coverage
There are 6 production Docker image variants. Only the main nonroot variant is tested:
| Variant | Dockerfile | Base Image | Tested? |
|---|---|---|---|
| Main (nonroot) | docker/Dockerfile | distroless/java17:nonroot | YES (built as integration_testing image) |
| GraalJS | docker/graaljs/Dockerfile | distroless/java17:nonroot | NO |
| Root | docker/root/Dockerfile | distroless/java17 | NO |
| Snapshot (debug) | docker/snapshot/Dockerfile | distroless/java17:debug-nonroot | NO |
| Root Snapshot | docker/root-snapshot/Dockerfile | distroless/java17 | NO |
| Local build | docker/local/Dockerfile | distroless/java17:nonroot | NO |
The integration tests always build with --build-arg source=copy (local JAR). The default source=download mode (downloads from Sonatype) used by real users is never tested.
What Docker Features Are Tested
- Basic container startup and HTTP API responsiveness
- Environment variable handling (
MOCKSERVER_SERVER_PORT,SERVER_PORT,PROXY_REMOTE_HOST,PROXY_REMOTE_PORT,MOCKSERVER_LOG_LEVEL,MOCKSERVER_INITIALIZATION_JSON_PATH,MOCKSERVER_PROPERTY_FILE,MOCKSERVER_PERSIST_EXPECTATIONS,MOCKSERVER_PERSISTED_EXPECTATIONS_PATH) - Volume mounts for configuration files and persisted state
- Command-line argument passing (
-serverPort) - Multi-container networking (bridge network between client and server)
- HTTP/2 support (via
nghttpin the forward-with-override test)
What Docker Features Are NOT Tested
| Feature | Status |
|---|---|
| Health checks | No HEALTHCHECK instruction in any Dockerfile. MOCKSERVER_LIVENESS_HTTP_GET_PATH exists but is disabled by default. |
| Graceful shutdown (signal handling) | No test verifies docker stop drains connections or persists state. |
| Multi-arch (ARM64) | CI builds linux/amd64,linux/arm64 but integration tests only run on native arch. |
JVM options (JVM_OPTIONS env var) | Supported by Helm chart but never tested via Docker Compose. |
/libs/* classpath extension | Entrypoint includes /libs/* on classpath for custom JARs but no test mounts into /libs/. |
| Custom TLS certificates | Forward-with-override uses HTTPS via nghttp but no test exercises custom certs or mTLS. |
| Resource limits / memory constraints | No test verifies behaviour under memory pressure. |
What Helm Features Are Tested
The 5 Helm tests cover basic deployment, custom image tags, custom server port, inline configuration, and inter-service proxy forwarding. All use the same validation pattern: create expectation via PUT, verify response via GET.
What Helm Features Are NOT Tested
| Feature | In Chart? | Tested? |
|---|---|---|
Ingress (ingress.yaml, 52 lines) | YES | NO |
| Service types (ClusterIP, LoadBalancer) | YES | NO (only NodePort) |
| Resource limits | YES | NO |
ConfigMap (app.config.enabled) | YES | NO |
| Probes (readiness/liveness) | YES (hardcoded) | Implicit only (via --wait) |
| Affinity / tolerations / node selectors | YES | NO |
| Pod annotations / security context | YES | NO |
| Replica count >1 | YES | NO |
helm test hook (service-test.yaml) | YES | NO (never invoked) |
helm lint / helm template | N/A | NO (not run anywhere) |
mockserver-config chart | YES (separate chart) | NO (zero tests) |
mountedLibsConfigMapName | YES | NO |
Performance Tests
The docker_build/performance/Dockerfile provides a k6-based performance testing image built on grafana/k6. The scenarios (smoke / load / stress / soak) and their threshold gates live in mockserver-performance-test/k6/; CI lints them on every change and runs an opt-in load test on manual/scheduled builds.
Test Utilities
mockserver-testing Module
Shared test utilities available to all modules:
| Class | Purpose |
|---|---|
PrintOutCurrentTestRunListener | JUnit RunListener that prints STARTED/FINISHED/FAILED/IGNORED with timing |
Assert | Custom assertion helpers: assertContains, assertDoesNotContain, assertSameEntries |
Retries | Retry logic for flaky/async operations: tryWaitForSuccess(runnable, maxAttempts, interval) |
TempFileWriter | Temporary file creation for tests |
IsDebug | Detects if running under a debugger; adjusts timeout units (seconds vs. minutes) |
PrintOutCurrentTestRunListener
Configured globally via Surefire/Failsafe in the root pom.xml:
<properties>
<listener>org.mockserver.test.PrintOutCurrentTestRunListener</listener>
</properties>
Supports three output modes controlled by -Dmockserver.testOutput:
| Mode | Default | Behaviour |
|---|---|---|
verbose | Yes (local) | Prints STARTED: and FINISHED: with duration for every test |
quiet | CI | Prints dots (.) for pass, F for failures, S for skipped, with per-class summaries |
summary | No | Prints per-class pass/fail counts with failure details only |
Test Configuration
Surefire Configuration (Root pom.xml)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<forkedProcessTimeoutInSeconds>1800</forkedProcessTimeoutInSeconds>
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
<systemPropertyVariables>
<mockserver.logLevel>${mockserver.testLogLevel}</mockserver.logLevel>
</systemPropertyVariables>
<argLine>@{argLine} -Duser.language=en -Duser.country=GB
-Dmockserver.testOutput=${mockserver.testOutput}
${mockserver.testArgLine}</argLine>
<disableXmlReport>${disableXmlReport}</disableXmlReport>
<redirectTestOutputToFile>${redirectTestOutputToFile}</redirectTestOutputToFile>
<properties>
<property>
<name>listener</name>
<value>org.mockserver.test.PrintOutCurrentTestRunListener</value>
</property>
</properties>
</configuration>
</plugin>
Failsafe Configuration (Root pom.xml)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<forkedProcessTimeoutInSeconds>1800</forkedProcessTimeoutInSeconds>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
<systemPropertyVariables>
<mockserver.logLevel>${mockserver.testLogLevel}</mockserver.logLevel>
<project.version>${project.version}</project.version>
<project.basedir>${project.basedir}</project.basedir>
</systemPropertyVariables>
<argLine>@{argLine} -Duser.language=en -Duser.country=GB
-Dmockserver.testOutput=${mockserver.testOutput}
${mockserver.testArgLine}</argLine>
<disableXmlReport>${disableXmlReport}</disableXmlReport>
<redirectTestOutputToFile>${redirectTestOutputToFile}</redirectTestOutputToFile>
<properties>
<property>
<name>listener</name>
<value>org.mockserver.test.PrintOutCurrentTestRunListener</value>
</property>
</properties>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
Parallelization
| Level | Mechanism | CI | Local |
|---|---|---|---|
| Module-level | Maven -T flag | -T 1C (1 thread/core) | -T 3C (3 threads/core) |
| Maven Invoker tests | <parallelThreads> | 2 threads | 2 threads |
mockserver-core unit tests | Two-phase Surefire: phase 1 parallel=classes/threadCount=4; phase 2 sequential | 4 threads (phase 1) | 4 threads (phase 1) |
| Other modules | Default (1 fork/module) | Default | Default |
mockserver-core uses a two-phase Surefire configuration: the default execution runs most unit tests in parallel (parallel=classes, threadCount=4), while a second execution (sequential-tests) runs a curated list of state-sensitive or timing-sensitive tests single-threaded. Tests excluded from the parallel phase include MockServerEventLogTest, HttpStateTest, template engine tests, and others that have wall-clock timing assertions or shared static state. All other modules run Surefire with its default (single-threaded) settings.
Maven Profiles (Test-Related)
| Profile | Activation | Purpose |
|---|---|---|
kill_mockserver_instances | Auto on Unix (/usr/bin/env exists) | Kills stray MockServer processes during clean phase via scripts/stop_MockServer.sh |
Test Skip Flags
| Flag | Where Used | Effect |
|---|---|---|
-DskipTests | Various scripts | Skips Surefire + Failsafe + Invoker + Gradle tests |
-Dmaven.test.skip=true | local_release.sh | Skips test compilation and execution |
${skipTests} | mockserver-netty/pom.xml | Controls Invoker (<skipInvocation>) and Gradle tests (<skip>) |
Test Data and Fixtures
Test resources are located in src/test/resources/ across modules:
| Module | Resource Types |
|---|---|
mockserver-core | OpenAPI specs (YAML/JSON), JSON schemas, XML schemas, TLS certificates/keys, initializer JSON files, binary files (PNG) |
mockserver-netty | TLS certificates and keys (RSA and EC), CSR configs, initializer JSON |
mockserver-war | XML schema, Tomcat catalina.properties |
mockserver-proxy-war | Tomcat catalina.properties |
mockserver-junit-jupiter | Mockito mock-maker-inline config |
mockserver-integration-testing | XML schema |
Test Coverage Tooling
JaCoCo (jacoco-maven-plugin) is configured in the parent mockserver/pom.xml with four execution goals:
| Goal | Phase | Purpose |
|---|---|---|
prepare-agent | initialize | Instruments classes for unit test coverage |
prepare-agent-integration | pre-integration-test | Instruments classes for integration test coverage |
report | verify | Generates per-module unit test coverage report |
report-integration | verify | Generates per-module integration test coverage report |
Reports are generated in each module's target/site/jacoco/ directory. See AI-Assisted Development for current coverage numbers by module.
Known Issues
Test Anti-Patterns
| Pattern | Count | Details |
|---|---|---|
| Mega-test methods (>200 lines) | 6 | Largest: shouldHandleInvalidOpenAPIJsonRequest() at 1994 lines in HttpStateTest |
| Excessive mocking (>100 mocks) | 2 | MockServerClientTest (130), HttpActionHandlerTest (109) |
| TODO comments about missing coverage | 4 | NottableStringMultiMapContainAllTest, HttpRequestsPropertiesMatcherTest |
CI Test Execution
Buildkite
The scripts/buildkite_quick_build.sh script runs the full build inside a mockserver/mockserver:maven Docker container:
./mvnw -T 1C clean install -Djava.security.egd=file:/dev/./urandom \
-Dmockserver.testOutput=quiet -DdisableXmlReport=false \
-DredirectTestOutputToFile=true -Dmockserver.testLogLevel=INFO \
"-Dmockserver.testArgLine=-Dmockserver.maxLogEntries=10000 -Dmockserver.maxExpectations=5000"
| Property | Value |
|---|---|
| JVM heap | -Xms2048m -Xmx6144m |
| Maven parallelism | -T 1C (1 thread per CPU core) |
| Test output | quiet (dots + failure details) |
| XML reports | Enabled (-DdisableXmlReport=false) |
| Test output redirection | Enabled (-DredirectTestOutputToFile=true) |
| Test log level | INFO (-Dmockserver.testLogLevel=INFO) |
| Timeout | 60 minutes |
| Build artefacts | **/*.log files collected |
All tests (unit + integration + Maven Invoker + Gradle integration) run in a single monolithic Buildkite step. There is no separation into different CI jobs for different test types.
Local Development
The scripts/local_quick_build.sh script:
- Sets 8GB heap allocation
- Uses Java 17 (
/usr/libexec/java_home -v 17) - Runs parallel Maven build (
-T 3C) - Runs container integration tests with
SKIP_JAVA_BUILD=true
./scripts/local_quick_build.sh
./scripts/local_single_test.sh
./scripts/local_single_module.sh