Поведение Wiremock с отслеживанием состояния не работает должным образом в нескольких сценариях

У меня есть вспомогательная функция тестирования createUser, которая отправляет HTTP-запрос к серверному API для создания пользователя. Серверный API вызывает метод на клиенте Auth0 для создания пользователя. Ответы, которые у меня есть, установлены для URL-адреса клиента Auth0 /api/v2/users.

Я тестирую службу с двумя типами пользователей — владельцем учетной записи и приглашенным пользователем. Я дважды вызываю помощника перед всеми тестами:

const owner = await createUser('[email protected]');
const invitee = await createUser('[email protected]');

И я ожидаю, что owner будет иметь [email protected] в качестве электронного письма и [email protected] электронное письмо для invitee .

Чтобы вернуть два разных ответа, я использовал сценарии Wiremock. И на данный момент у меня есть такие ответы:

Пользователь №1

 {
  "scenarioName": "user-scenario",
  "requiredScenarioState": "Started",
  "newScenarioState": "owner-user",
  "request": {
    "method": "POST",
    "urlPattern": "/api/v2/users"
  },
  "response": {
    "status": 201,
    "headers": {
      "Content-Type": "application/json"
    },
    "jsonBody": {
      "email": "[email protected]"
    }
  }
}

Пользователь №2

{
  "scenarioName": "user-scenario",
  "requiredScenarioState": "owner-user",
  "request": {
    "method": "POST",
    "urlPattern": "/api/v2/users"
  },
  "response": {
    "status": 201,
    "headers": {
      "Content-Type": "application/json"
    },
    "jsonBody": {
      "email": "[email protected]"
    }
  }
}

Когда я запускаю тесты, Wiremock возвращает второй ответ для обоих вызовов createUser. Второй ответ был создан после первого, и Wiremock отдает приоритет последнему созданному ответу. Я решил установить priority: 1 на первый ответ, чтобы заставить Wiremock вернуть его и, следовательно, изменить состояние сценария. Это сработало только при первом тестовом прогоне, но не для последующих. Иногда, если я удаляю образ Wiremock Docker и запускаю контейнер с нуля, он возвращает ответы, как и ожидалось, но затем продолжает возвращать второй ответ для обоих вызовов.

Что я делаю неправильно, и если это не так, как я настроил сценарии, каковы могут быть возможные причины такого несоответствия?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Несколько способов снять шкуру с этой кошки - третий (шаблон ответа), вероятно, лучший.

Понимание сценариев

Первый запрос переводит сценарий в состояние owner-user, и после этого все запросы будут возвращать пользователя № 2 на время жизни экземпляра WireMock — в вашем случае контейнера докера — если он не будет сброшен.

Вы можете сбросить его так: PUT /__admin/scenarios/user-scenario/Started.

Состояние сценария хранится в памяти, поэтому перезапуск контейнера также должен сбросить состояние на Started.

Смотрите WireMock | Поведение с сохранением состояния | Сброс одного сценария

Использование лучшего соответствия, чтобы избежать сценариев

Возможно, вам вообще не понадобится использовать сценарии. Вы можете использовать тело запроса POST, чтобы решить, какую заглушку вызывать, исходя из отправляемого вами адреса электронной почты.

Предполагая, что полезная нагрузка вашего запроса выглядит следующим образом:

{
  "email": "[email protected]" 
}

Вы можете сопоставить тело запроса так:

Пользователь №1

{
  "request": {
    "method": "POST",
    "urlPattern": "/api/v2/users",
      "bodyPatterns": [
        {
          "matchesJsonPath": {
            "expression": "$.email",
            "equalTo": "[email protected]",
          }
        }
      ]
  },
  "response": {
    "status": 201,
    "headers": {
      "Content-Type": "application/json"
    },
    "jsonBody": {
      "email": "[email protected]"
    }
  }
}

Пользователь №2

{
  "request": {
    "method": "POST",
    "urlPattern": "/api/v2/users",
    "bodyPatterns": [
      {
        "matchesJsonPath": {
          "expression": "$.email",
          "equalTo": "[email protected]",
        }
      }
    ]
  },
  "response": {
    "status": 201,
    "headers": {
      "Content-Type": "application/json"
    },
    "jsonBody": {
      "email": "[email protected]"
    }
  }
}

Смотрите WireMock | Сопоставление запросов | Путь JSON для получения подробной информации.

Использование шаблонов ответов для уменьшения количества заглушек

Вы можете использовать значения, переданные WireMock в запросе в ответе, используя шаблон ответа следующим образом:

{
  "request": {
    "method": "POST",
    "urlPattern": "/api/v2/users"
  },
  "response": {
    "status": 201,
    "headers": {
      "Content-Type": "application/json"
    },
    "transformers": ["response-template"],
    "jsonBody": {
      "email": "{{jsonPath request.body '$.email'}}"
    }
  }
}

Смотрите WireMock | Шаблоны ответов | Помощник JSONPath для деталей.

Существует также множество помощников для генерации случайных данных в различных форматах, если вам нужно, чтобы каждый запрос возвращал какое-то другое значение (например, UUID) — см. WireMock | Шаблоны ответов | Помощник по случайным значениям для деталей.

Привет, @Robert Elliot, извини за такую ​​запоздалую реакцию, но твой ответ решил мою проблему. Я использовал bodyPatterns, чтобы вернуть ответ на основе электронной почты. Большое спасибо!

buterfly85 24.01.2023 16:35

Другие вопросы по теме