Docs SDK Guide

SDK Guide

Mockarty provides official SDK libraries for Go, Python, Java, and Kotlin. All SDKs offer type-safe access to the Mockarty API for mock management, testing, fuzzing, contract testing, performance testing, and more.

Every SDK follows the same design principles: fluent builders for mock creation, consistent API naming across languages, environment-variable-based defaults, and first-class testing integration.

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 Stable
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.21+, zero external dependencies (stdlib only).

Python

# pip
pip install mockarty

# Poetry
poetry add mockarty

# With async HTTP/2 support
pip install mockarty[async]

Requirements: Python 3.9+.

Java (Maven)

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

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

Java (Gradle)

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

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

Kotlin

implementation("ru.mockarty:mockarty-kotlin:1.0.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 (requires mockarty[async])
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

All SDKs support configuration via environment variables as defaults:

Variable Description Default
MOCKARTY_BASE_URL Mockarty server URL http://localhost:5770
MOCKARTY_API_KEY API authentication key (none)
MOCKARTY_NAMESPACE Default namespace 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().Results(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.results()

Java

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

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().start(config);
client.recorder().listSessions();
client.recorder().getSession("session-id");
client.recorder().stopRecording("session-id");
client.recorder().getEntries("session-id");
client.recorder().createMocks("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

BETA – Run controlled fault injection experiments on Kubernetes clusters. See Chaos Engineering Guide for full documentation.

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("$.body.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("$.body.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. Prefer environment variables for CI/CD. Set MOCKARTY_BASE_URL and MOCKARTY_API_KEY in your pipeline environment instead of hardcoding values.

  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 Verify curl $MOCKARTY_BASE_URL/health returns ok
MockartyUnauthorizedError (401) Missing or invalid API token Create a token in Admin → API Tokens and set MOCKARTY_API_KEY
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 hangs with no timeout Default client has no timeout Set timeout in the client builder (e.g. MockartyClient(timeout=30))
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.