Docs SDK Guide

SDK Guide

Use a Mockarty SDK when you want to create mocks or run tests from your application code or CI pipeline. Choose Go, Python, Java, or Kotlin below; each has examples for the tasks it supports.

Before you start, you need a running Mockarty server, an API token with access to your namespace, and that namespace’s name. Install your language’s package, configure the client, then try the Mocks API. For a first look at the product itself, start with the Quick Start.

About URLs in examples: All examples use localhost:5770 as the default Mockarty address. If your instance runs on a remote server, replace localhost:5770 with its actual address (e.g. https://mockarty.company.com or http://192.168.1.50:5770). See Tips & Useful Features for details.

Driving the system under test: beyond configuring mocks, the SDKs ship test clients for gRPC, Kafka, RabbitMQ, SOAP, GraphQL, SSE, WebSocket with auto-step capture into TCM external runs. See SDK Protocol Clients for the cross-language reference.

Supported Languages

Language Package GitHub Status
Go github.com/mockarty/mockarty-go github.com/mockarty/mockarty-go Stable
Python mockarty (PyPI) github.com/mockarty/py-sdk Beta
Java ru.mockarty:mockarty-java (Maven Central) github.com/mockarty/java-sdk Stable
Kotlin ru.mockarty:mockarty-kotlin (Maven Central) github.com/mockarty/java-sdk Stable

Installation

Go

go get github.com/mockarty/mockarty-go

Requirements: Go 1.25+. The core client uses only the Go standard library; the optional protocol and testing sub-packages pull their own dependencies.

Python

# pip
pip install mockarty

# Poetry
poetry add mockarty

# Optional HTTP/2 support for the async client
pip install mockarty[async]

Requirements: Python 3.9+.

Java (Maven)

<dependency>
    <groupId>ru.mockarty</groupId>
    <artifactId>mockarty-java</artifactId>
    <version>0.3.0</version>
</dependency>

<!-- JUnit 5 extension (test scope) -->
<dependency>
    <groupId>ru.mockarty</groupId>
    <artifactId>mockarty-junit5</artifactId>
    <version>0.3.0</version>
    <scope>test</scope>
</dependency>

Java (Gradle)

// Core SDK
implementation("ru.mockarty:mockarty-java:0.3.0")

// JUnit 5 extension
testImplementation("ru.mockarty:mockarty-junit5:0.3.0")

Kotlin

implementation("ru.mockarty:mockarty-kotlin:0.3.0")

Provides Kotlin DSL extensions on top of the Java SDK.

Client Configuration

Go

import mockarty "github.com/mockarty/mockarty-go"

client := mockarty.NewClient("http://localhost:5770",
    mockarty.WithAPIKey("mk_your_api_key"),   // API key authentication
    mockarty.WithNamespace("production"),      // Default namespace (default: "sandbox")
    mockarty.WithTimeout(10 * time.Second),   // HTTP timeout (default: 30s)
    mockarty.WithRetry(3, time.Second),       // Retry with exponential back-off
    mockarty.WithHTTPClient(customClient),    // Custom http.Client
    mockarty.WithLogger(slog.Default()),      // Structured logger
)

Python

from mockarty import MockartyClient, AsyncMockartyClient

# Synchronous client
client = MockartyClient(
    base_url="http://localhost:5770",
    api_key="mk_your_api_key",
    namespace="sandbox",
    timeout=30,
    max_retries=3,
)

# Async client (included in the base package)
async_client = AsyncMockartyClient(
    base_url="http://localhost:5770",
    api_key="mk_your_api_key",
)

# Context manager support
with MockartyClient() as client:
    client.mocks.create(mock)
    # client.close() is called automatically

# Async context manager
async with AsyncMockartyClient() as client:
    await client.mocks.create(mock)

Java

import ru.mockarty.MockartyClient;

// Builder pattern, AutoCloseable
try (MockartyClient client = MockartyClient.builder()
        .baseUrl("http://localhost:5770")
        .apiKey("mk_your_api_key")
        .namespace("sandbox")
        .timeout(Duration.ofSeconds(30))
        .build()) {

    client.mocks().create(mock);
}

Kotlin

import ru.mockarty.MockartyClient

// Shorthand factory
val client = MockartyClient.create("http://localhost:5770", "mk_your_api_key")

Environment Variables

Environment defaults differ by language. Python and Java read MOCKARTY_BASE_URL and MOCKARTY_API_KEY when you omit those constructor arguments; Java also reads MOCKARTY_NAMESPACE. Go takes its URL in NewClient and uses WithAPIKey and WithNamespace for the other values. In Python, pass namespace= explicitly; the core Python client does not read MOCKARTY_NAMESPACE automatically.

Variable Description Default
MOCKARTY_BASE_URL Server URL for Python and Java http://localhost:5770
MOCKARTY_API_KEY API token for Python and Java (none)
MOCKARTY_NAMESPACE Default namespace for Java; Python test plugins also use it sandbox

API Reference

Mocks API

Create, read, update, and delete mocks. Supports batch operations, soft delete/restore, versioning, and log access.

Go

// Create
resp, err := client.Mocks().Create(ctx, mock)

// Get / List
mock, err := client.Mocks().Get(ctx, "mock-id")
list, err := client.Mocks().List(ctx, &mockarty.ListMocksOptions{
    Namespace: "production",
    Tags:      []string{"users"},
    Limit:     20,
})

// Update / Delete / Restore
updated, err := client.Mocks().Update(ctx, "mock-id", mock)
err = client.Mocks().Delete(ctx, "mock-id")
err = client.Mocks().Restore(ctx, "mock-id")

// Batch operations
err = client.Mocks().BatchCreate(ctx, mocks)
err = client.Mocks().BatchDelete(ctx, ids)
err = client.Mocks().BatchRestore(ctx, ids)

// Logs and versions
logs, err := client.Mocks().Logs(ctx, "mock-id", &mockarty.LogsOptions{Limit: 50})
versions, err := client.Mocks().ListVersions(ctx, "mock-id")
version, err := client.Mocks().GetVersion(ctx, "mock-id", "v2")
err = client.Mocks().RestoreVersion(ctx, "mock-id", "v1")

// Additional operations
patched, err := client.Mocks().Patch(ctx, "mock-id", map[string]any{"priority": 10})
err = client.Mocks().DeleteLogs(ctx, "mock-id")
err = client.Mocks().CopyToNamespace(ctx, []string{"mock-1"}, "production")
err = client.Mocks().MoveToFolder(ctx, []string{"mock-1"}, "folder-id")
err = client.Mocks().BatchUpdateTags(ctx, []string{"mock-1", "mock-2"}, []string{"v2"})

Python

# Create
result = client.mocks.create(mock)

# Get / List
mock = client.mocks.get("mock-id")
page = client.mocks.list(namespace="sandbox", limit=10)
for m in page.items:
    print(m.id)

# Delete / Restore
client.mocks.delete("mock-id")
client.mocks.restore("mock-id")

Java

// Create
client.mocks().create(mock);

// Get / List
Mock mock = client.mocks().get("mock-id");

// Delete / Restore
client.mocks().delete("mock-id");
client.mocks().restore("mock-id");

Stores API

Access global and chain stores for stateful mock scenarios.

Go

// Global store
store, err := client.Stores().GlobalGet(ctx)
err = client.Stores().GlobalSet(ctx, "counter", 42)
err = client.Stores().GlobalDelete(ctx, "key1")
err = client.Stores().GlobalDeleteMany(ctx, "key1", "key2") // delete multiple keys

// Chain store
chainStore, err := client.Stores().ChainGet(ctx, "chain-id")
err = client.Stores().ChainSet(ctx, "chain-id", "status", "completed")
err = client.Stores().ChainDelete(ctx, "chain-id", "key")

Python

# Global store
client.stores.global_set("counter", 0)
data = client.stores.global_get()

# Chain store
client.stores.chain_set("order-flow", "orderId", "abc-123")
chain_data = client.stores.chain_get("order-flow")

Java

// Global store
client.stores().globalSet("counter", 0);
Map<String, Object> store = client.stores().globalGet();

// Chain store
client.stores().chainSet("registration-flow", "step", "1");

Namespaces API

Create and list namespaces for mock isolation.

Go

err := client.Namespaces().Create(ctx, "production")
namespaces, err := client.Namespaces().List(ctx)

Python

client.namespaces.create("production")
namespaces = client.namespaces.list()

Java

client.namespaces().create("production");

Collections & Test Runs API

Manage API test collections: list, create, execute, export, and duplicate.

Go

// List / Get
collections, err := client.Collections().List(ctx)
col, err := client.Collections().Get(ctx, "collection-id")

// Execute a single collection or multiple
result, err := client.Collections().Execute(ctx, "collection-id")
result, err = client.Collections().ExecuteMultiple(ctx, []string{"col-1", "col-2"})

// Create / Update / Delete
created, err := client.Collections().Create(ctx, &mockarty.Collection{Name: "My Suite"})
updated, err := client.Collections().Update(ctx, "collection-id", col)
err = client.Collections().Delete(ctx, "collection-id")

// Export (Postman-compatible JSON)
data, err := client.Collections().Export(ctx, "collection-id")

// Test Runs
runs, err := client.TestRuns().List(ctx)
run, err := client.TestRuns().Get(ctx, "run-id")
err = client.TestRuns().Cancel(ctx, "run-id")
err = client.TestRuns().Delete(ctx, "run-id")

Python

collections = client.collections.list()
result = client.collections.execute("collection-id")

Java

client.collections().list();
client.collections().execute("collection-id");

Performance Testing API

Run load tests, manage configurations and schedules, compare results.

Go

task, err := client.Perf().Run(ctx, &mockarty.PerfConfig{
    Name:     "load-test-orders",
    Duration: "30s",
    VUs:      50,
})
err = client.Perf().Stop(ctx, "task-id")
results, err := client.Perf().ListResults(ctx)
result, err := client.Perf().GetResult(ctx, "result-id")
comparison, err := client.Perf().Compare(ctx, []string{"result-1", "result-2"})

// Configs & Schedules
configs, err := client.Perf().ListConfigs(ctx)
schedules, err := client.Perf().ListSchedules(ctx)

Python

task = client.perf.run(config)
client.perf.stop("task-id")
results = client.perf.list_results()

Java

client.perf().run(config);
client.perf().stop("task-id");
client.perf().listResults();

Load-test DSL → k6 script

Author a load test with a fluent builder and export it as a k6-compatible
JavaScript script — no hand-writing k6 boilerplate. The generated script is
self-contained: your target() is baked in as a runnable default
(const BASE_URL = __ENV.BASE_URL || '…'), so it works out of the box and stays
overridable at run time with mockarty-cli perf run script.js -e BASE_URL=….

Terminal methods:

  • toK6Script() / to_k6_script() — the k6 JS string (write to a .js file, run anywhere k6 or mockarty-cli perf run runs).
  • toPerfConfig() / to_perf_config() — a perf-config object (script + vus/duration/stages/thresholds/env) for mockarty-cli perf run --from-config.
  • save(path) / SaveConfig(path) — write that perf-config JSON to disk.

Go

script := mockarty.NewLoadTest("checkout-load").
    Target("http://localhost:5770").
    Get("/health").
    Post("/stubs/sandbox/v1/charge", map[string]any{"amount": 100}).
    Stages(mockarty.Stage("30s", 20), mockarty.Stage("1m", 20), mockarty.Stage("10s", 0)).
    ThinkTime(0.5).
    Threshold("http_req_duration", "p(95)<500").
    ToK6Script()

os.WriteFile("checkout.js", []byte(script), 0o644)
// then: mockarty-cli perf run checkout.js

Python

from mockarty import LoadTest

script = (
    LoadTest("checkout-load")
    .target("http://localhost:5770")
    .get("/health")
    .post("/stubs/sandbox/v1/charge", body={"amount": 100})
    .stages([("30s", 20), ("1m", 20), ("10s", 0)])
    .think_time(0.5)
    .threshold("http_req_duration", "p(95)<500")
    .to_k6_script()
)

open("checkout.js", "w").write(script)
# then: mockarty-cli perf run checkout.js

Java

String script = LoadTestBuilder.named("checkout-load")
    .target("http://localhost:5770")
    .get("/health")
    .post("/stubs/sandbox/v1/charge", Map.of("amount", 100))
    .stage("30s", 20).stage("1m", 20).stage("10s", 0)
    .thinkTime(0.5)
    .threshold("http_req_duration", "p(95)<500")
    .toK6Script();

Files.writeString(Path.of("checkout.js"), script);
// then: mockarty-cli perf run checkout.js

The three SDKs emit an identical script for the same DSL, so a load profile
authored in one language runs unchanged everywhere.

Fuzzing API

Start security fuzzing sessions, manage configurations, and triage findings.

Go

task, err := client.Fuzzing().Start(ctx, &mockarty.FuzzingConfig{
    Name:      "fuzz-users-api",
    TargetURL: "http://localhost:5770",
})
err = client.Fuzzing().Stop(ctx, "run-id")
result, err := client.Fuzzing().GetResult(ctx, "run-id")
findings, err := client.Fuzzing().ListFindings(ctx)
finding, err := client.Fuzzing().GetFinding(ctx, "finding-id")
err = client.Fuzzing().TriageFinding(ctx, "finding-id", "accepted", "Known behavior")

// Quick fuzz, schedules, and imports
summary, err := client.Fuzzing().GetSummary(ctx)
schedules, err := client.Fuzzing().ListSchedules(ctx)

Python

task = client.fuzzing.start(config)
findings = client.fuzzing.list_findings()

Java

client.fuzzing().start(config);
client.fuzzing().listFindings();

Contract Testing API

Validate mocks against API specifications, verify providers, manage Pact contracts, run can-i-deploy checks, and use the API Registry for cross-team contract governance.

Go

// Validate mocks against an OpenAPI/Swagger spec
result, err := client.Contracts().ValidateMocks(ctx, &mockarty.ContractValidationRequest{
    SpecURL:   "https://petstore.swagger.io/v2/swagger.json",
    Namespace: "production",
})

// Verify a live provider against a contract
verify, err := client.Contracts().VerifyProvider(ctx, &mockarty.ContractValidationRequest{
    SpecURL:   "https://api.example.com/openapi.json",
    TargetURL: "https://api.example.com",
})

// Pact support
pacts, err := client.Contracts().ListPacts(ctx)
published, err := client.Contracts().PublishPact(ctx, &mockarty.Pact{
    Consumer: "frontend",
    Provider: "user-service",
    Spec:     pactJSON,
})
deploy, err := client.Contracts().CanIDeploy(ctx, canIDeployReq)
mocks, err := client.Contracts().GenerateMocksFromPact(ctx, "pact-id")

// Detect drift between contract and live service
drift, err := client.Contracts().DetectDrift(ctx, driftReq)

// API Registry: publish, subscribe, check breaking changes
entries, err := client.Contracts().ListRegistry(ctx, "")
entry, err := client.Contracts().PublishToRegistry(ctx, &mockarty.RegistryEntry{
    ServiceName: "user-service",
    SpecType:    "openapi",
    Version:     "2.0.0",
})
sub, err := client.Contracts().Subscribe(ctx, "entry-id", &mockarty.Subscription{
    ServiceName:      "frontend",
    NotifyOnBreaking: true,
})
impact, err := client.Contracts().CheckImpact(ctx, "entry-id", newSpecContent)

// Configs & Results
configs, err := client.Contracts().ListConfigs(ctx)
results, err := client.Contracts().ListResults(ctx)

Python

result = client.contracts.validate_mocks({"specUrl": "...", "namespace": "production"})
pacts = client.contracts.list_pacts()
deploy = client.contracts.can_i_deploy(request)
entries = client.contracts.list_registry()

Java

client.contracts().validateMocks(request);
client.contracts().listPacts();
client.contracts().canIDeploy(request);
client.contracts().listRegistry("");

Recorder API

Capture live traffic and generate mocks from recorded requests.

Go

// Start a recording session
session, err := client.Recorder().StartRecording(ctx, &mockarty.RecorderSession{
    Name:      "capture-login-flow",
    TargetURL: "https://api.example.com",
})

// Manage sessions
sessions, err := client.Recorder().ListSessions(ctx)
session, err = client.Recorder().GetSession(ctx, "session-id")
err = client.Recorder().StopRecording(ctx, "session-id")
err = client.Recorder().RestartRecording(ctx, "session-id")

// Work with recorded entries
entries, err := client.Recorder().GetEntries(ctx, "session-id")
err = client.Recorder().AnnotateEntry(ctx, "session-id", "entry-id", annotation)
err = client.Recorder().ReplayEntry(ctx, "session-id", "entry-id")

// Generate mocks from recorded traffic
mocks, err := client.Recorder().CreateMocksFromSession(ctx, "session-id", nil)

// Export session as HAR
har, err := client.Recorder().ExportSession(ctx, "session-id")

// CA certificate management (for HTTPS recording)
caStatus, err := client.Recorder().GetCAStatus(ctx)
err = client.Recorder().GenerateCA(ctx)
caCert, err := client.Recorder().DownloadCA(ctx)

Python

session = client.recorder.start_recording(config)
client.recorder.stop_recording("session-id")
entries = client.recorder.get_entries("session-id")
mocks = client.recorder.create_mocks_from_session("session-id")

Java

RecorderSession s = client.recorder().startRecording(config);
client.recorder().listSessions();
client.recorder().getSession("session-id");
client.recorder().stopRecording("session-id");
client.recorder().getEntries("session-id");
client.recorder().createMocksFromSession("session-id", null);

Health API

Check server health, liveness, and readiness.

Go

health, err := client.Health().Check(ctx)
err = client.Health().Live(ctx)
err = client.Health().Ready(ctx)

Python

health = client.health.check()
print(health.status)

Java

boolean healthy = client.health().ready();

Chaos Engineering API

Preview. Run controlled fault injection experiments on Kubernetes clusters. Check the available safeguards on your installation before starting. See the Chaos Engineering Guide.

Go

// Cluster profiles (connect to Kubernetes)
profiles, err := client.Chaos().ListProfiles(ctx)
profile, err := client.Chaos().CreateProfile(ctx, &mockarty.ChaosProfile{
    Name:           "staging-cluster",
    KubeconfigData: base64Kubeconfig,
    Context:        "staging-ctx",
})
connResult, err := client.Chaos().TestProfile(ctx, profile.ID)

// List presets (predefined experiment templates)
presets, err := client.Chaos().ListPresets(ctx)

// Create and run experiment
exp, err := client.Chaos().Create(ctx, &mockarty.ChaosExperiment{
    Name:        "pod-kill-test",
    Namespace:   "staging",
    DurationSec: 300,
    Faults: []mockarty.FaultConfig{{
        Type:           mockarty.FaultPodKillRandom,
        GracePeriodSec: 5,
    }},
    Target: mockarty.TargetConfig{
        Mode:     mockarty.TargetModeAll,
        Selector: map[string]string{"app": "frontend"},
    },
    Safety: mockarty.SafetyConfig{
        MinReplicasAlive: 1,
        AutoRollback:     true,
    },
})
err = client.Chaos().Run(ctx, exp.ID)

// Monitor experiment
metrics, err := client.Chaos().GetMetrics(ctx, exp.ID)
events, err := client.Chaos().GetEvents(ctx, exp.ID)
err = client.Chaos().Abort(ctx, exp.ID) // emergency stop

// Get report and download
report, err := client.Chaos().GetReport(ctx, exp.ID)
htmlReport, err := client.Chaos().DownloadReport(ctx, exp.ID, "html")

// Cluster operations (ad-hoc)
topology, err := client.Chaos().GetTopology(ctx, profile.ID, "default")
err = client.Chaos().KillPod(ctx, "staging", "frontend-abc123", 0)
podDetail, err := client.Chaos().GetPodDetail(ctx, "staging", "frontend-abc123")
logs, err := client.Chaos().GetPodLogs(ctx, "staging", "frontend-abc123", "app", 100)
result, err := client.Chaos().ScaleDeployment(ctx, "staging", "frontend", 3)

// Operator management
opStatus, err := client.Chaos().GetOperatorStatus(ctx, "chaos-system")
manifest, err := client.Chaos().GenerateOperatorManifest(ctx, "https://mockarty.example.com", "")

Python

# List presets
presets = client.chaos.list_presets()

# Create and run experiment
exp = client.chaos.create({
    "name": "pod-kill-test",
    "namespace": "staging",
    "durationSec": 300,
    "faults": [{"type": "pod_kill_random"}],
    "target": {"mode": "all", "selector": {"app": "frontend"}},
    "safety": {"minReplicasAlive": 1, "autoRollback": True},
})
client.chaos.run(exp["id"])

# Get report
report = client.chaos.get_report(exp["id"])

Java

// Create and run experiment
ChaosExperiment exp = client.chaos().create(new ChaosExperiment()
    .setName("pod-kill-test")
    .setNamespace("staging")
    .setDurationSec(300));
client.chaos().run(exp.getId());

// Get report
Map<String, Object> report = client.chaos().getReport(exp.getId());

Mock Builder (Fluent API)

All SDKs provide a fluent builder for constructing mocks with full type safety.

HTTP Mock with Conditions

Go

mock := mockarty.NewMockBuilder().
    ID("create-order").
    HTTP(func(h *mockarty.HTTPBuilder) {
        h.Route("/api/orders").
          Method("POST").
          HeaderCondition("Authorization", mockarty.AssertNotEmpty, nil)
    }).
    Response(func(r *mockarty.ResponseBuilder) {
        r.Status(201).
          Header("Content-Type", "application/json").
          JSONBody(map[string]any{
              "orderId": "$.fake.UUID",
              "amount":  "$.req.amount",
              "status":  "created",
          })
    }).
    Build()

Python

from mockarty import MockBuilder, AssertAction

mock = (
    MockBuilder.http("/api/orders", "POST")
    .id("create-order")
    .namespace("production")
    .tags("orders", "v2")
    .priority(10)
    .condition("$.amount", AssertAction.NOT_EMPTY)
    .header_condition("Authorization", AssertAction.NOT_EMPTY)
    .respond(201, body={
        "orderId": "$.fake.UUID",
        "amount": "$.req.amount",
        "status": "created",
    })
    .callback("https://webhook.site/test", method="POST", body={"event": "order.created"})
    .ttl(7200)
    .build()
)

Java

import ru.mockarty.builder.MockBuilder;
import ru.mockarty.model.AssertAction;

Mock mock = MockBuilder.http("/api/orders", "POST")
    .id("create-order")
    .condition("$.amount", AssertAction.NOT_EMPTY, null)
    .headerCondition("Authorization", AssertAction.NOT_EMPTY, null)
    .queryCondition("format", AssertAction.EQUALS, "json")
    .respond(201, Map.of(
        "orderId", "$.fake.UUID",
        "amount", "$.req.amount",
        "status", "created"
    ))
    .callback("https://webhook.example.com/notify", "POST",
        Map.of("event", "order.created"))
    .ttl(3600)
    .build();

Kotlin

import ru.mockarty.dsl.*
import ru.mockarty.model.AssertAction

client.createMock {
    id = "create-order"
    namespace = "production"
    tags = listOf("orders", "v2")

    http {
        route = "/api/orders"
        method = "POST"
        headerCondition("Authorization", AssertAction.NOT_EMPTY)
    }

    respond {
        statusCode = 201
        body = mapOf(
            "orderId" to "$.fake.UUID",
            "amount" to "$.req.amount",
            "status" to "created"
        )
    }

    ttl = 3600
}

gRPC Mock

Go

mock := mockarty.NewMockBuilder().
    ID("grpc-user").
    GRPC(func(g *mockarty.GRPCBuilder) {
        g.Service("UserService").Method("GetUser")
    }).
    Response(func(r *mockarty.ResponseBuilder) {
        r.JSONBody(map[string]any{"name": "John", "email": "john@test.com"})
    }).
    Build()

Python

grpc_mock = (
    MockBuilder.grpc("user.UserService", "GetUser")
    .id("grpc-get-user")
    .condition("$.id", AssertAction.NOT_EMPTY)
    .respond(200, body={"id": "$.req.id", "name": "$.fake.FirstName"})
    .build()
)

Java

Mock mock = MockBuilder.grpc("UserService", "GetUser")
    .serverName("grpc-server")
    .condition("$.user_id", AssertAction.EQUALS, "123")
    .respond(200, Map.of("name", "John", "email", "john@test.com"))
    .build();

MCP Mock

Go

mock := mockarty.NewMockBuilder().
    ID("mcp-weather").
    MCPConfig(func(m *mockarty.MCPBuilderCtx) {
        m.Tool("get_weather")
    }).
    Response(func(r *mockarty.ResponseBuilder) {
        r.JSONBody(map[string]any{"temperature": 22, "city": "$.req.city"})
    }).
    Build()

Python

mcp_mock = (
    MockBuilder.mcp("get_weather")
    .id("mcp-weather")
    .respond(200, body={"temperature": 22, "city": "$.req.city"})
    .build()
)

Java

Mock mock = MockBuilder.mcp("search_documents")
    .condition("$.query", AssertAction.NOT_EMPTY, null)
    .respond(200, Map.of("results", List.of("doc1", "doc2")))
    .build();

Proxy and OneOf

Go

// Proxy to a real backend
proxy := mockarty.NewMockBuilder().
    ID("proxy").
    HTTP(func(h *mockarty.HTTPBuilder) {
        h.Route("/api/external").Method("GET")
    }).
    ProxyTo("https://real-api.example.com").
    Build()

// OneOf responses (random or sequential)
flaky := mockarty.NewMockBuilder().
    ID("flaky-service").
    HTTP(func(h *mockarty.HTTPBuilder) {
        h.Route("/api/data").Method("GET")
    }).
    OneOfConfig(mockarty.OneOfOrderRandom,
        func(r *mockarty.ResponseBuilder) { r.Status(200).JSONBody("ok") },
        func(r *mockarty.ResponseBuilder) { r.Status(500).Error("boom") },
    ).
    Build()

Python

# Proxy
proxy = (
    MockBuilder.http("/api/external", "GET")
    .id("proxy")
    .proxy_to("https://real-api.example.com")
    .build()
)

Java

// Proxy
Mock proxy = MockBuilder.http("/api/real-service", "GET")
    .proxyTo("https://api.example.com")
    .build();

// OneOf responses (ordered)
Mock flaky = MockBuilder.http("/api/flaky", "GET")
    .oneOfOrdered(
        new ContentResponse().statusCode(200).payload(Map.of("status", "ok")),
        new ContentResponse().statusCode(500).error("server error"),
        new ContentResponse().statusCode(200).payload(Map.of("status", "recovered"))
    )
    .build();

Error Handling

The Mockarty REST API emits a single uniform JSON envelope for every 4xx/5xx
failure:

{
  "error":      "human-readable, sanitized message",
  "code":       "not_found",
  "request_id": "8c3a…d12"
}
  • error — safe message; never contains SQL strings, stack traces, or file
    paths. Display directly to end users.
  • code — stable machine-readable identifier from a closed set
    (validation, unauthorized, forbidden, not_found, conflict,
    rate_limit, unavailable, external, internal). Branch on this
    field instead of parsing the message.
  • request_id — server-side correlation ID. Include in support tickets so
    operators can locate the matching log line.

Each SDK parses the envelope and exposes typed exceptions / sentinel errors
that match the code field. Older Mockarty servers emit only error; the
SDKs and CLI fall back to HTTP-status dispatch in that case.

Go

import "errors"

_, err := client.Mocks().Get(ctx, "nonexistent")
if errors.Is(err, mockarty.ErrNotFound) {
    // Handle 404 — works against both new (code="not_found") and legacy servers.
}

var apiErr *mockarty.APIError
if errors.As(err, &apiErr) {
    fmt.Printf("status=%d code=%q msg=%q request_id=%q\n",
        apiErr.StatusCode, apiErr.Code, apiErr.Message, apiErr.RequestID)
}

Python

from mockarty.errors import MockartyNotFoundError, MockartyAPIError

try:
    mock = client.mocks.get("non-existent")
except MockartyNotFoundError as e:
    print(f"not found (request_id={e.request_id})")
except MockartyAPIError as e:
    # e.code is the stable kind ("validation", "rate_limit", ...).
    # e.request_id is the server-side correlation ID.
    print(f"status={e.status_code} code={e.code} msg={e.message} request_id={e.request_id}")

Java

import ru.mockarty.exception.MockartyException;
import ru.mockarty.exception.MockartyNotFoundException;

try {
    client.mocks().get("non-existent");
} catch (MockartyNotFoundException e) {
    System.out.println("Mock not found");
} catch (MockartyException e) {
    System.out.printf("API error %d: %s%n", e.getStatusCode(), e.getMessage());
}

Testing Integration

Go: Testing Helpers

The Go SDK provides *T helper methods that automatically clean up resources when the test ends:

func TestUserAPI(t *testing.T) {
    client := mockarty.NewClient("http://localhost:5770",
        mockarty.WithAPIKey("mk_test_key"),
    )

    // Create namespace with auto-cleanup
    client.SetupNamespaceT(t, "test-ns")

    // Create mock with auto-cleanup
    mock := client.CreateMockT(t, mockarty.NewMockBuilder().
        ID("test-user-get").
        Namespace("test-ns").
        HTTP(func(h *mockarty.HTTPBuilder) {
            h.Route("/api/users/1").Method("GET")
        }).
        Response(func(r *mockarty.ResponseBuilder) {
            r.Status(200).JSONBody(map[string]any{"id": "1", "name": "Test"})
        }).
        Build(),
    )
    // mock is automatically deleted when the test ends
    _ = mock
}

Python: pytest Fixtures

pip install mockarty[test]
# conftest.py
pytest_plugins = ["mockarty.testing.fixtures"]

# test_example.py
def test_create_mock(mock_cleanup):
    from mockarty import MockBuilder
    mock = MockBuilder.http("/test", "GET").respond(200, body="ok").build()
    created = mock_cleanup(mock)
    assert created.id is not None

Java: JUnit 5 Extension

import ru.mockarty.junit5.MockartyTest;
import ru.mockarty.junit5.MockartyServer;
import ru.mockarty.MockartyClient;
import ru.mockarty.builder.MockBuilder;

@MockartyTest(namespace = "test", cleanupAfterEach = true)
class UserApiTest {

    @Test
    void shouldReturnUser(MockartyClient client, MockartyServer server) {
        server.createMock(MockBuilder.http("/api/users/1", "GET")
            .respond(200, Map.of("id", 1, "name", "John"))
            .build());

        // Your test code here...
        // Mocks are automatically cleaned up after each test
    }
}

Kotlin: DSL in Tests

@MockartyTest(namespace = "test", cleanupAfterEach = true)
class UserApiTest {

    @Test
    fun `should return user`(client: MockartyClient) {
        client.createMock {
            id = "test-user"
            http {
                route = "/api/users/1"
                method = "GET"
            }
            respond {
                statusCode = 200
                body = mapOf("id" to 1, "name" to "John")
            }
        }

        // Test assertions here...
    }
}

Best Practices

  1. Use namespaces for isolation. Each test suite or environment should use its own namespace to avoid mock conflicts.

  2. Set TTL on test mocks. Always set a ttl on mocks created during testing so they are automatically cleaned up even if your teardown fails.

  3. Use the mock builder for type safety. The fluent builder API catches errors at compile time (or IDE time) rather than at runtime.

  4. Clean up mocks after tests. Use the built-in test helpers (SetupNamespaceT in Go, mock_cleanup in Python, @MockartyTest in Java/Kotlin) for automatic cleanup.

  5. Use stores for stateful scenarios. Chain stores allow you to simulate multi-step workflows (e.g., create order -> pay -> ship) with state carried between mock calls.

  6. Keep credentials in CI secrets. Pass the server URL and API token to your client from the pipeline environment. Python and Java can read the variables above automatically; in Go, read them and pass them to NewClient and WithAPIKey.

  7. Use batch operations for setup. When creating multiple mocks for a test scenario, use BatchCreate to reduce HTTP round-trips.

  8. Version your mocks. Use the versioning API to track mock changes and roll back when needed.

Troubleshooting

Error Cause Fix
MockartyConnectionError / connection refused Mockarty server not running, or base_url points to the wrong host/port Check the configured URL and that its /health endpoint returns HTTP 200
MockartyUnauthorizedError (401) Missing or invalid API token Create a token in Admin → API Tokens and pass it to the client as shown above
MockartyForbiddenError (403) with invalid license No valid license applied to the server Apply a license key in Administration → License, or contact your administrator
MockartyForbiddenError (403) on namespace Token scoped to a different namespace Use a token with access to the target namespace, or switch namespaces in the client
MockartyConflictError (409) on create Mock with the same ID already exists Use upsert/update, or generate a unique ID
MockartyNotFoundError on resolve Mock exists but namespace/route/method don’t match Confirm the mock fields via list or the UI; check for trailing slashes and method case
Faker placeholders show as literal strings in the response payload sent as a plain string instead of a template object Pass a dict/Map with "$.fake.*" values, not a pre-rendered string
Request times out The server or network did not respond within the configured timeout Check server reachability; adjust the timeout if this operation needs longer than the default 30 seconds
Tests fail intermittently in parallel Multiple tests sharing the same namespace and mock IDs Use a unique namespace per test suite or randomize mock IDs

For protocol-specific troubleshooting (gRPC, MCP, Kafka, etc.), see the relevant section in the API Reference.

Test framework integration

Each SDK ships a framework layer that hooks into your favourite test
runner so the per-test outcome — status, steps, captured logs, small
attachments — flows back to a Mockarty test case as a synthetic case
run. You decorate the test, run it, and the case-run history appears in
the UI without writing any glue code.

Python — pytest plugin

After pip install mockarty the pytest plugin auto-loads. Set
MOCKARTY_BASE_URL and MOCKARTY_API_KEY (or pass mockarty_client as
a fixture) and decorate the tests you want to track:

from mockarty.testing import test_case, attach_report, step, attach

@test_case("CASE-LOGIN-1", plan="qa-smoke")
@attach_report
def test_login(mockarty_client):
    with step("submit form"):
        ...
    with step("verify response"):
        attach("response.json", response.text, content_type="application/json")
        assert response.status_code == 200
  • @test_case("CASE-ID") binds the test to an existing case. Pass
    auto_create=True with name="..." to create the case the first
    time the test runs.
  • @attach_report opts the test into the upload.
  • with step("...") records a TCM step. Steps nest. When
    allure-pytest is installed each step is mirrored to Allure too.
  • attach(name, body, content_type=...) adds a small artefact that
    shows up next to the case run in the UI.

Java — JUnit 5 extension

Add mockarty-junit5 to your test dependencies and put @MockartyTest
on the class. Per-method annotations control case binding:

@MockartyTest(namespace = "qa")
class LoginTest {

    @Test
    @TestCase("CASE-LOGIN-1")
    @AttachReport
    void login(MockartyClient client) {
        try (Step s = Step.open("submit form")) {
            // ...
        }
        Step.run("verify", () -> assertEquals(200, response.status()));
    }
}

The same primitives are available through Step.open(...) /
Step.run(...) and Attachments.attach(...).

Go — testing.T helpers

The Go SDK exposes helpers to bind a *testing.T to a Mockarty
namespace and clean up created mocks on test exit. To trigger a Test
Plan run from a Go test and assert on its outcome:

func TestLoginFlow(t *testing.T) {
    c := mockarty.NewClient(os.Getenv("MOCKARTY_BASE_URL"),
        mockarty.WithAPIKey(os.Getenv("MOCKARTY_API_KEY")))
    c.RunPlanT(t, "qa-smoke")  // fails the test on plan-run failure
}

Defaults

All three frameworks fail-soft: when no Mockarty client is reachable
(missing env, server unreachable) the decorators / annotations no-op so
the test still runs locally. The framework never fails your test
because reporting failed.

Reports from selected CI jobs

When Mockarty starts a saved CI job for selected test cases, it supplies a private
MOCKARTY_CI_CONTEXT environment variable. The SDK’s existing external-run
Report operation uses that context to match the test’s stable ID and full name
against the selected items. Send the same identities configured for the selected
test. An unknown or ambiguous identity is rejected; the SDK does not create a
replacement case or attach the result to another launch.

Upload every selected result, then report the command outcome once with
CompleteGroup (Go), complete_group (Python), or completeGroup (Java).
Use passed, failed, or cancelled. A passed command does not make missing test
results pass. The group remains accountable for all selected items.

For example, Python code running inside the job can finish its uploads as follows:

import os
from mockarty.ci_job_context import load_ci_job_context

job = load_ci_job_context(os.environ["MOCKARTY_CI_CONTEXT"])
# Upload the test results with client.external_runs.report(...).
client.external_runs.complete_group(job.callback, "passed", namespace=job.namespace)

Go uses LoadCIJobContext, job.Callback() and
client.ExternalRuns().CompleteGroup(ctx, job.Namespace, job.Callback(), status).
Java uses CIJobContext.load, job.callback() and
client.externalRuns().completeGroup(job.getNamespace(), job.callback(), status).
Existing Report signatures and ordinary uploads remain available.

Keep the private context out of logs, labels, parameters and environment report
files. SDK environment writers omit it; selected uploads also remove it from
metadata and reject attachments containing its value. Selected result and group
completion POSTs are not automatically retried after an uncertain response.
Inspect the existing launch before an explicit retry.

For Allure directories, UploadAllureDir / upload_allure_dir /
uploadAllureDir filters matching selected results before resolving their
media, and preflights every selected body before the first result request.
Selected reports allow up to 1000 steps, 256 KiB per inline attachment and
1 MiB of inline attachments per result. Use the CLI for large files and
container fixtures, and call group completion after the uploads.
The Go incremental externalruns.Client write methods refuse selected job
context; use the finalized ExternalRuns().Report workflow shown above.