当没有请求匹配时,使用 WireMock 实现不同的响应

Implement different response with WireMock when no request(s) match

我正在尝试存根 RESTful API。资源之一 return 资源(确实)找到时的详细信息,或 HTTP 404 (Not Found) 最终没有给定资源的资源 URL.

这是我的简化版 stub/mapping:

{
  "mappings": [
    {
      "name": "Retrieve Items",
      "request": {
        "headers": {
          "accept": {
            "caseInsensitive": true,
            "equalTo": "application/json"
          }
        },
        "method": "GET",
        "urlPathPattern": "/api/items/[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}"
      },
      "response": {
        "bodyFileName": "items-api/responses/retrieve/{{ request.pathSegments.[2] }}.json",
        "headers": {
          "content-type": "application/json"
        },
        "status": 200
      }
    }
  ]
}

然后我有几个 JSON 文件(在 /home/wiremock/__files/items-api/responses/retrieve/ 中以匹配请求 — 但我找不到实现 HTTP 404 的方法(Not Found) 场景:

{
  "timestamp": {{ now }},
  "status": 404,
  "error": "Not Found",
  "message": null,
  "path": "{{ request.path }}"
}

使用此配置,我从 WireMock 返回(预期的,但对我的用例没有用)响应,即未找到文件名 uuid-sent-in-request.json

目前有没有办法实现这种行为?

目前您需要编写 ResponseDefinitionTransformer 才能获得您正在寻找的行为。

它需要检查传入的参数ResponseDefinition是否需要一个文件,然后如果是这样检查文件是否存在通过做这样的事情:

try {
    fileSource.getBinaryFileNamed(bodyFileName).readContents();
} catch (FileNotFoundException e) {
    return WireMock.notFound().withBody("custom body");
}

// Otherwise return the unmodified response definition

Tom 的回答同样有效。我认为他的解决方案的好处是它们不依赖于特定的请求 URL,但我的建议是为将与其特定 JSON 文件匹配的文件进行特定映射,以及一个包罗万象的映射对于不匹配的文件。通过为具有 JSON 响应的请求分配更高的优先级,WireMock 将首先检查那些,如果请求不匹配该映射中指定的任何值,则将继续检查第二个映射是否匹配,并且return 一个 404。

{
  "mappings": [
    {
      "name": "Retrieve Items - Success",
      "priority": 1, // arbitrary number lower than the second priority
      "request": {
        "headers": {
          "accept": {
            "caseInsensitive": true,
            "equalTo": "application/json"
          }
        },
        "method": "GET",
        "urlPathPattern": "/api/items/(UUID1|UUID2|UUID3|UUID4)"
      },
      "response": {
        "bodyFileName": "items-api/responses/retrieve/{{ request.pathSegments.[2] }}.json",
        "headers": {
          "content-type": "application/json"
        },
        "status": 200
      }
    },
    {
      "name": "Retrieve Items - 404 Not Found",
      "priority": 5, // arbitrary number that is higher than 1
      "request": {
        "headers": {
          "accept": {
            "caseInsensitive": true,
            "equalTo": "application/json"
          }
        },
        "method": "GET",
        "urlPathPattern": "/api/items/[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}"
      },
      "response": {
        "status": 404
      }
    }
  ]
}