Response stubs
Pane поддерживает два режима подмены ответов на запросы, проходящие через прокси:
- Stub — апстрим не вызывается, отдаётся целиком заранее подготовленный ответ.
- Patch — реальный запрос идёт на сервер, его ответ перехватывается и поверх него применяется список патчей.
Patch удобен в сценариях, где клиент зависит от server-generated полей (token, timestamps, ids) — они остаются настоящими, а ты подменяешь только нужные значения для теста.
Где это настраивается
Sidebar → Rules → коллекция → правило в режиме Patch — forward, then mutate.
Правило матчится по тем же признакам, что и в Stub-режиме: host glob, method, path glob, query/body параметры. Если правило срабатывает — после получения ответа от сервера движок применяет список патчей.
Синтаксис path
Путь — это dot-notation, который ходит по «виртуальному дереву ответа»:
| Префикс | Что меняет |
|---|---|
status | HTTP-статус ответа |
headers.<Name> | Заголовок ответа (case-insensitive) |
body.<dot.path> | Поле в JSON-теле |
<dot.path> | Тоже body — префикс body. опционален, так что user.fio ≡ body.user.fio |
Внутри body-пути:
a.b.c— вложенный объект.a.b[0]— элемент массива по индексу.a.b[-]— добавить в конец массива (только в opset/append).
Виды операций
| op | Что делает |
|---|---|
set | Установить значение в path. Если родительских объектов нет — создаст. |
delete | Удалить поле объекта или элемент массива по index. |
append | Добавить элемент в массив (path указывает на массив). |
Значение (value)
Парсится как JSON, с fallback на строку:
qwerty→ строка"qwerty"777→ числоtrue/false/null→ bool / null{"a":1}→ объект["x","y"]→ массив
Если нужно подменить поле строкой, похожей на число ("123"), пиши "123" с кавычками.
Пример 1. Подмена одного поля
Сервер отвечает:
{ "user": { "uid": 2715, "fio": "ТГ ГИС МТ", ... }, "token": { "id": "ed821640d251...", ... }}Хочу: имя fio подменить на тестовое, оставить настоящий token.
Mode: Patch
Match: POST /api/auth
Patches:
op | path | value------+----------------+------------set | user.fio | "Тестовый"Реальный токен останется живым, следующие запросы пройдут авторизацию.
Пример 2. Заменить массив объектов
Сервер отвечает списком ~130 объектов:
{ "objects": [ {...}, {...}, ... 130 элементов ], "_links": {...} }Хочу: оставить в массиве только один объект (для теста UI пагинации, выпадайки, и т.п.).
Вариант A — одно правило (рекомендуется)
Заменить весь массив сразу. В value — JSON-массив с одним элементом.
op | path | value------+----------------+----------------------------------------------------------set | body.objects | [{"uid":6,"id":6,"name":"ЗТК объект","priority":2}]Обрати внимание: путь body.objects (без [0]!) и value начинается с [ — это JSON-массив, не объект.
Вариант B — два патча по очереди
Если удобнее в логике «очистить + добавить»:
op | path | value---------+----------------+-------------------------set | body.objects | []append | body.objects | {"uid":6,"id":6,"name":"ЗТК объект","priority":2}set ... = [] очищает массив, append добавляет один элемент. Патчи применяются по порядку.
Чего НЕ делать (типичная ошибка)
op | path | value------+-------------------+----------------set | body.objects[0] | {...} ← заменит только нулевой элементПри такой записи массив длиной 130 не меняется — просто первый элемент перезаписывается, остальные 129 остаются. UI всё ещё видит длинный список.
Правило: [0] — это индекс конкретного элемента, а сам body.objects (без индекса) — весь массив.
Пример 3. Подменить статус и заголовок
op | path | value------+----------------------------+-------------set | status | 401set | headers.X-Pane-Stubbed | "true"set | body.error | "unauthorized"Пример 4. Удалить поле и добавить новое
op | path | value---------+----------------------------+---------delete | body.user.email |set | body.user.role | "admin"Задержка (delay)
В обоих режимах есть поле delay (ms) в Response-секции. В Stub-режиме задержка применяется перед отправкой ответа. В Patch-режиме — после получения реального ответа от сервера, перед записью клиенту. Удобно симулировать медленный сервер.
Что попадёт в Captures
- Stub-режим →
state='stubbed'. - Patch-режим →
state='patched'. В вкладке Response видно уже подменённое тело — так клиент его и получил.
Когда патч молча не сработает
- Body не является валидным JSON → body-патчи пропускаются (warning в лог), status/headers-патчи всё равно применяются.
- Content-Type ответа не json-подобный → body не парсится, body-патчи пропускаются.
- Путь указывает на несуществующий индекс массива в
delete/append(дляappendиндексов вообще не должно быть). - Невалидный JSON в value → трактуется как строка, что иногда даёт неожиданное
"true"вместоtrue.
Если правило не работает как ожидалось — посмотри, что реально лежит в captures для этого запроса, и сверь путь.