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-стабы принимаются как есть — переписывать не нужно.
Смотрите также
- Гид по миграции с WireMock — серверная
WireMock-совместимость (когда Mockarty уже работает как long-lived
сервис и вы общаетесь с ним WireMock-клиентами). - Гид по SDK — основной SDK-референс.
- Контейнер CLI (Docker) — запуск образа без
testcontainers.