Test Container (Go & Java)
Mockarty ships a programmatic test-container API so your tests can spin
up a fresh mock server per test (or per package) without managing the
Docker lifecycle by hand. It is the drop-in replacement for
wiremock-testcontainers (Java) and wiremockcontainer (Go) — point
your existing test bodies at the Mockarty container class and they keep
working, because the running image exposes the same WireMock
/__admin/* API plus Mockarty’s native admin API on the same port.
The container itself runs the real mockarty-cli mock serve process
baked into the mockarty/cli:<version>-mock Docker image. There is no
embedded engine — the test container behaves identically to a
production CLI install, just managed by your test runner.
When to use it
- You have an existing WireMock testcontainer suite and want a one-line
swap to Mockarty. - You want isolated mocks per CI shard or test package and prefer a
programmatic API over a manually manageddocker run. - You want to record traffic with a HAR file (recorder export, browser
dev-tools, Mockarty Recorder) and replay it inside the same test.
Prerequisites
- Docker reachable from the test process (the test harness skips
cleanly when there is no daemon). - The image
mockarty/cli:latest-mockavailable locally or via a
registry your test environment can pull from.
Go quickstart
package mypkg_test
import (
"context"
"net/http"
"testing"
"github.com/mockarty/mockarty-go/mockartycontainer"
)
func TestMyAPI(t *testing.T) {
ctx := context.Background()
c := mockartycontainer.MustRun(ctx, t,
mockartycontainer.WithImage("mockarty/cli:latest-mock"),
mockartycontainer.WithMappings("./testdata/mocks"),
)
resp, err := http.Get(c.URL() + "/api/users/1")
if err != nil { t.Fatal(err) }
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("status = %d", resp.StatusCode)
}
}
MustRun fails the test on any start error and registers a
t.Cleanup hook so the container is torn down automatically when the
test ends. If you prefer manual lifecycle management, call
mockartycontainer.Run(ctx, opts...) and defer container.Terminate(ctx).
Options
| Option | Effect |
|---|---|
WithImage(ref) |
Override the container image (private registry, pinned digest). |
WithFormat(f) |
Stub dialect: FormatAuto (default), FormatWireMock, FormatMockoon, FormatMockarty. |
WithMappings(hostDir) |
Bind-mount a directory of stub files; loaded at startup. |
WithHAR(hostFile) |
Bind-mount a HAR file; mocks are generated at startup. |
WithStubFile(hostFile) |
Mount a single stub file. Repeatable. |
WithPort(p) |
Pin the host TCP port. Use 0 (default) for ephemeral. |
WithEnv(k, v) |
Inject an extra env-var into the container. |
WithLogger(w) |
Stream the container’s stdout+stderr to a writer. |
WithStartupTimeout(d) |
Bump the wait-for-ready deadline (default 60s). |
Endpoint URLs
The container multiplexes three admin surfaces on the same listener:
| Method | URL | Purpose |
|---|---|---|
| Catch-all | c.URL() + "/<your-route>" |
Hit any mocked endpoint. |
| WireMock | c.WireMockURL() + "/mappings" |
List, create, reset WireMock stubs. |
| Mockarty | c.MockartyURL() + "/mocks" |
Native Mockarty admin API. |
| Health | c.MetricsURL() + "/health" |
Liveness probe. |
Runtime mock registration
err := c.AddWireMockStub(ctx, map[string]any{
"request": map[string]any{"method": "GET", "url": "/api/runtime"},
"response": map[string]any{"status": 200, "body": `{"hi":"world"}`},
})
For native Mockarty mocks (multi-protocol, gRPC, MCP, Kafka context):
err := c.AddMockartyMock(ctx, mockartySDKMock)
To reset between assertions:
err := c.Reset(ctx)
HAR replay
c := mockartycontainer.MustRun(ctx, t,
mockartycontainer.WithHAR("./testdata/traffic.har"),
)
The HAR file is mounted at /har/traffic.har and replayed at startup
via the MOCKARTY_HAR_REPLAY env-var; HAR-generated mocks are layered
on top of any WithMappings(...) stubs.
Java quickstart
import ru.mockarty.testcontainers.Format;
import ru.mockarty.testcontainers.MockartyContainer;
@Testcontainers
class MyApiTest {
@Container
static MockartyContainer mockarty = new MockartyContainer()
.withFormat(Format.AUTO)
.withMappingDirectory(Path.of("src/test/resources/mocks"))
.withHarReplay(Path.of("src/test/resources/traffic.har"));
@Test
void hitsStub() throws Exception {
HttpClient http = HttpClient.newHttpClient();
HttpResponse<String> resp = http.send(
HttpRequest.newBuilder(URI.create(mockarty.url() + "/api/users/1")).GET().build(),
BodyHandlers.ofString());
assertEquals(200, resp.statusCode());
}
}
The Java module ships the MockartyContainerExtension JUnit5 extension
so plain field declarations work without @Testcontainers.
Direct docker run alternative
If you cannot use a programmatic container client, the same image is
runnable directly:
docker run --rm -p 8080:8080 -p 9090:9090 \
-v "$(pwd)/mocks:/mocks:ro" \
-e MOCKARTY_MOCK_DIR=/mocks \
mockarty/cli:latest-mock
The two surfaces are equivalent — the test-container wrapper merely
manages the lifecycle for you.
Migrating from WireMock testcontainers
| Before | After |
|---|---|
new WireMockContainer() |
new MockartyContainer() |
.withMapping("name", ...) |
.withMappingDirectory(Path.of("...")) |
WireMockContainer#getBaseUrl() |
MockartyContainer#url() |
wm.resetMappings() |
mockarty.reset() |
mockartycontainer.New(...) |
identical |
WireMock JSON stubs are accepted verbatim — no rewrite required.
Related
- WireMock Migration Guide — server-side
WireMock compatibility (use this when you already run Mockarty as a
long-lived process and just want to talk to it from WireMock clients). - SDK Guide — the parent SDK reference.
- CLI Container (Docker) — running the CLI
image directly without testcontainers.