Документация SDK Test Container (Go и Java)

Test Container (Go и Java)

Mockarty предоставляет программный API для запуска mock-сервера в
тесте: можно поднимать свежий контейнер на каждый тест (или на пакет)
без ручного управления Docker. Это полноценная замена
wiremock-testcontainers (Java) и wiremockcontainer (Go) — достаточно
поменять класс контейнера, и существующие тесты продолжают работать,
потому что внутри образа поднимается тот же WireMock-совместимый
/__admin/* плюс нативный Mockarty admin API на том же порту.

Внутри контейнера работает реальный процесс mockarty-cli mock serve
из образа mockarty/cli:<version>-mock. Встроенного движка нет —
поведение совпадает с обычным CLI-инсталлятором.

Когда использовать

  • Уже есть набор WireMock-тестов на testcontainers и нужен бесшовный
    переход на Mockarty.
  • Требуется изоляция моков по CI-шардам или тест-пакетам, а
    программное API удобнее, чем docker run.
  • Нужно проиграть записанный HAR-трафик (Recorder, DevTools браузера)
    прямо внутри теста.

Требования

  • Доступный Docker в окружении теста (без daemon тесты корректно
    пропускаются).
  • Образ mockarty/cli:latest-mock локально или в реестре, до которого
    достанет тестовое окружение.

Быстрый старт (Go)

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 падает с t.Fatalf при ошибке старта и регистрирует
t.Cleanup, который автоматически останавливает контейнер по
завершении теста. Если нужен ручной контроль жизненного цикла —
используйте mockartycontainer.Run(ctx, opts...) и
defer container.Terminate(ctx).

Опции

Опция Эффект
WithImage(ref) Переопределить образ (private registry, pinned digest).
WithFormat(f) Диалект стабов: FormatAuto (по умолчанию), FormatWireMock, FormatMockoon, FormatMockarty.
WithMappings(hostDir) Bind-mount каталога стабов; загружается при старте.
WithHAR(hostFile) Bind-mount HAR-файла; моки генерируются при старте.
WithStubFile(hostFile) Маунт одного файла. Можно вызывать многократно.
WithPort(p) Зафиксировать host-порт. По умолчанию 0 — ephemeral.
WithEnv(k, v) Добавить переменную окружения.
WithLogger(w) Стримить stdout+stderr контейнера в writer.
WithStartupTimeout(d) Поднять wait-for-ready (по умолчанию 60s).

URLs

Назначение URL
Поймать любой mocked-роут c.URL() + "/<your-route>"
WireMock admin c.WireMockURL() + "/mappings"
Mockarty admin c.MockartyURL() + "/mocks"
Health c.MetricsURL() + "/health"

Регистрация мока в рантайме

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"}`},
})

Для нативных Mockarty-моков (gRPC, MCP, Kafka и т.д.):

err := c.AddMockartyMock(ctx, mockartySDKMock)

Сброс состояния между assertion’ами:

err := c.Reset(ctx)

HAR replay

c := mockartycontainer.MustRun(ctx, t,
    mockartycontainer.WithHAR("./testdata/traffic.har"),
)

Файл монтируется в /har/traffic.har; CLI поднимет моки из HAR
при старте через переменную MOCKARTY_HAR_REPLAY. HAR-моки
накладываются поверх WithMappings(...).

Быстрый старт (Java)

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());
    }
}

В модуле также есть MockartyContainerExtension для JUnit5 — поля
работают без явного @Testcontainers.

Альтернатива через docker run

Если programmatic-клиент использовать нельзя, тот же образ запускается
напрямую:

docker run --rm -p 8080:8080 -p 9090:9090 \
  -v "$(pwd)/mocks:/mocks:ro" \
  -e MOCKARTY_MOCK_DIR=/mocks \
  mockarty/cli:latest-mock

Поверхности эквивалентны — testcontainer-обёртка лишь управляет
жизненным циклом за вас.

Миграция с WireMock testcontainers

До После
new WireMockContainer() new MockartyContainer()
.withMapping("name", ...) .withMappingDirectory(Path.of("..."))
WireMockContainer#getBaseUrl() MockartyContainer#url()
wm.resetMappings() mockarty.reset()
mockartycontainer.New(...) без изменений

WireMock JSON-стабы принимаются как есть — переписывать не нужно.

Смотрите также