首页 > 解决方案 > 使用 openApi 后端模拟服务工作者

问题描述

我正在使用MSWOpenAPI 后端包。我想模拟展位浏览器服务器和测试服务器。我有 OpenAPI 定义可用的表格,我为 RTK 查询生成了 generate.ts(超出了这个问题的范围)。我想使用 OpenAPI 规范将它与 OpenAPI 后端一起使用,并为浏览器和测试生成 MSW 休息工作人员。

接下来是设置:

索引.tsx

import worker from './mocks/browser';

if (process.env.NODE_ENV === 'development') {
    worker.start();
}

模拟/浏览器.ts

import { setupWorker, rest } from 'msw';

import { OpenAPIBackend } from 'openapi-backend';
import type { Document } from 'openapi-backend';
import definition from './api.json';


// create our mock backend with openapi-backend
const api = new OpenAPIBackend({ definition: definition as Document });
api.register('notFound', (c, res, ctx) => res(ctx.status(404)));
api.registerHandler('notImplemented', async (c, req, res) => {
    const { status, mock } = await api.mockResponseForOperation(
        c.operation.operationId as string
    );
    return res.status(status).json(mock);
});
api.register('validationFail', (c, res, ctx) =>
    res(ctx.status(400), ctx.json({ error: c.validation.errors }))
);

const worker = setupWorker(
    rest.get('/*', (req) =>
        api.handleRequest({
            ...req,
            path: req.url.pathname,
            headers: req.headers.all(),
            method: req.method,
            body: req.body,
        })
    )
);


export default worker;

api.JSON

{
  "openapi": "3.0.1",
  "info": {
    "title": "Fetch API",
    "description": "Source of truth for Fetch dashboard",
    "version": "0.1.5"
  },
  "paths": {
    "/config": {
      "get": {
        "tags": [
          "Configuration"
        ],
        "summary": "Retreive configuration object",
        "description": "Returns configuration object (map) containing configuration parameters for UI (Map<String, String>)",
        "responses": {
          "200": {
            "description": "successfull operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "Map serialized to json object.",
                  "example": {
                    "FA_COLOR": "red",
                    "FA_NAME": "fetch"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/links": {
      "get": {
        "tags": [
          "Notifications & Links",
          "Walking Skeleton"
        ],
        "summary": "List all defined links for hospital",
        "description": "Retreives all defined links for hospital. Hospital ID is indirectly obtained from user identity.",
        "responses": {
          "200": {
            "description": "successfull operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Link"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kpis": {
      "get": {
        "tags": [
          "KPIS"
        ],
        "summary": "List all KPIs for hospital(s) that current user is managing.",
        "description": "Retreives all KPIs available for hospitals that current user is managing.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/KPI"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "KPI": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "enum": [
              "revenue",
              "labour"
            ]
          },
          "hospital_id": {
            "type": "string",
            "description": "id of hospital that this KPI describes"
          },
          "goal": {
            "type": "number",
            "description": "full month goal"
          },
          "actual": {
            "type": "number",
            "description": "actual result"
          },
          "mtd_goal": {
            "type": "number",
            "description": "month to date goal, so that we can track projected fulfillment of goal."
          },
          "details": {
            "type": "object",
            "description": "Semi-structured way of describing details of calculation. Every KPI will potentialiy be described differently."
          }
        },
        "required": [
          "id",
          "hospital_id",
          "goal",
          "actual",
          "mtd_goal"
        ]
      },
      "Link": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "unique id of link"
          },
          "hospital_id": {
            "type": "string",
            "description": "id of hospital that this Link is configured for"
          },
          "title": {
            "type": "string",
            "description": "human readable title for URL"
          },
          "description": {
            "type": "string",
            "description": "Description of current link (alt text , or tooltip)"
          },
          "url": {
            "type": "string",
            "description": "Location of external resource"
          },
          "urgent": {
            "type": "boolean",
            "description": "Is urgency of notification elevated?"
          },
          "count": {
            "type": "number",
            "description": "Actual notification value. How many 'tasks' are waiting manager in external system."
          },
          "updated_at": {
            "type": "integer",
            "description": "Date/time of last notification update",
            "format": "int64"
          },
          "children": {
            "type": "array",
            "description": "Since notifications are possibly presented in hierarchy all children of this notification will be gathered here",
            "items": {
              "$ref": "#/components/schemas/Link"
            }
          }
        },
        "required": [
          "id",
          "hospital_id",
          "title",
          "url"
        ],
        "example": [
          {
            "id": 1,
            "hospital_id": "001",
            "title": "Link1",
            "description": "description of Link1",
            "url": "https://www.example.com/link1",
            "urgent": true,
            "count": 1,
            "updated_at": 1631113184221,
            "children": [
              {
                "id": 2,
                "hospital_id": "001",
                "title": "Link2",
                "description": "description of Link2",
                "url": "https://www.example.com/link2",
                "urgent": true,
                "count": 1,
                "updated_at": 1631113184221
              }
            ]
          },
          {
            "id": 3,
            "hospital_id": "002",
            "title": "Link3",
            "description": "description of Link3",
            "url": "https://www.example.com/link3",
            "urgent": false,
            "count": 2,
            "updated_at": 1631113184221
          }
        ]
      }
    }
  }
}

组件.tsx

const { data: links, error, isLoading } = useGetLinksQuery({});

这是 localhost:3000/links

我得到的错误是:

mockServiceWorker.js:222 [MSW] Uncaught exception in the request handler for "GET http://localhost:3000/links":

Error: Unknown operation
    at OpenAPIValidator.validateRequest (http://localhost:3000/static/js/vendors~main.chunk.js:63911:13)
    at OpenAPIBackend.<anonymous> (http://localhost:3000/static/js/vendors~main.chunk.js:54246:45)
    at async OpenAPIBackend.handleRequest (http://localhost:3000/static/js/vendors~main.chunk.js:54152:22)

This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses
getResponse @ mockServiceWorker.js:222
async function (async)
getResponse @ mockServiceWorker.js:175
handleRequest @ mockServiceWorker.js:113
async function (async)
handleRequest @ mockServiceWorker.js:112
(anonymous) @ mockServiceWorker.js:271

网络选项卡提供:

Request URL: http://localhost:3000/links
Request Method: GET
Status Code: 500  (from service worker)
Referrer Policy: strict-origin-when-cross-origin

所有相关文章:https ://dev.to/epilot/testing-react-with-jest-and-openapi-mocks-8gc 和https://testing-library.com/docs/react-testing-library/example -介绍/

谢谢你。

标签: reactjstypescriptopenapireact-testing-librarymsw

解决方案


推荐阅读