Skip to content

Commit 8570947

Browse files
authored
Update testing example (#1268)
1 parent 359508a commit 8570947

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

docs/src/content/docs/advanced.md

+26-26
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ Let’s say we want to write our mocks in the following object structure, so we
2727
```
2828
{
2929
[pathname]: {
30-
[HTTP method]: {
31-
[HTTP status code]: { [some mock data] }
32-
}
30+
[HTTP method]: { status: [status], body: { …[some mock data] } };
3331
}
3432
}
3533
```
@@ -44,23 +42,22 @@ describe("My API test", () => {
4442
it("mocks correctly", async () => {
4543
mockResponses({
4644
"/users/{user_id}": {
47-
get: {
48-
200: { id: "user-id", name: "User Name" }, // ✅ Correct 200 response
49-
404: { code: "404", message: "User not found" }, // ✅ Correct 404 response
50-
},
45+
// ✅ Correct 200 response
46+
get: { status: 200, body: { id: "user-id", name: "User Name" } },
47+
// ✅ Correct 403 response
48+
delete: { status: 403, body: { code: "403", message: "Unauthorized" } },
5149
},
5250
"/users": {
53-
put: {
54-
201: { status: "success" }, // ✅ Correct 201 response
55-
},
51+
// ✅ Correct 201 response
52+
put: { 201: { status: "success" } },
5653
},
5754
});
5855

59-
// test 1: GET /users/{user_id}: 200 returned by default
56+
// test 1: GET /users/{user_id}: 200
6057
await fetch("/users/user-123");
6158

62-
// test 2: GET /users/{user_id}: 404 returned if `x-test-status` header sent
63-
await fetch("/users/user-123", { headers: { "x-test-status": 404 } });
59+
// test 2: DELETE /users/{user_id}: 403
60+
await fetch("/users/user-123", { method: "DELETE" });
6461

6562
// test 3: PUT /users: 200
6663
await fetch("/users", {
@@ -95,15 +92,22 @@ type FilterKeys<Obj, Matchers> = { [K in keyof Obj]: K extends Matchers ? Obj[K]
9592
type PathResponses<T> = T extends { responses: any } ? T["responses"] : unknown;
9693
type OperationContent<T> = T extends { content: any } ? T["content"] : unknown;
9794
type MediaType = `${string}/${string}`;
95+
type MockedResponse<T, Status extends keyof T = keyof T> = FilterKeys<
96+
OperationContent<T[Status]>,
97+
MediaType
98+
> extends never
99+
? { status: Status; body?: never }
100+
: {
101+
status: Status;
102+
body: FilterKeys<OperationContent<T[Status]>, MediaType>;
103+
};
98104

99105
/**
100106
* Mock fetch() calls and type against OpenAPI schema
101107
*/
102108
export function mockResponses(responses: {
103109
[Path in keyof Partial<paths>]: {
104-
[Method in keyof Partial<paths[Path]>]: {
105-
[Status in keyof Partial<PathResponses<paths[Path][Method]>>]: FilterKeys<OperationContent<PathResponses<paths[Path][Method]>[Status]>, MediaType>;
106-
};
110+
[Method in keyof Partial<paths[Path]>]: MockedResponse<PathResponses<paths[Path][Method]>>;
107111
};
108112
}) {
109113
fetchMock.mockResponse((req) => {
@@ -112,13 +116,11 @@ export function mockResponses(responses: {
112116
if (!mockedPath || (!responses as any)[mockedPath]) throw new Error(`No mocked response for ${req.url}`); // throw error if response not mocked (remove or modify if you’d like different behavior)
113117
const method = req.method.toLowerCase();
114118
if (!(responses as any)[mockedPath][method]) throw new Error(`${req.method} called but not mocked on ${mockedPath}`); // likewise throw error if other parts of response aren’t mocked
115-
const desiredStatus = req.headers.get("x-status-code");
116-
const body = (responses as any)[mockedPath][method];
117-
return {
118-
status: desiredStatus ? parseInt(desiredStatus, 10) : 200,
119-
body: JSON.stringify((desiredStatus && body[desiredStatus]) ?? body[200]),
120-
};
121-
});
119+
if (!(responses as any)[mockedPath][method]) {
120+
throw new Error(`${req.method} called but not mocked on ${mockedPath}`);
121+
}
122+
const { status, body } = (responses as any)[mockedPath][method];
123+
return { status, body: JSON.stringify(body) };
122124
}
123125

124126
// helper function that matches a realistic URL (/users/123) to an OpenAPI path (/users/{user_id}
@@ -146,9 +148,7 @@ export function findPath(actual: string, testPaths: string[]): string | undefine
146148
```ts
147149
export function mockResponses(responses: {
148150
[Path in keyof Partial<paths>]: {
149-
[Method in keyof Partial<paths[Path]>]: {
150-
[Status in keyof Partial<PathResponses<paths[Path][Method]>>]: FilterKeys<OperationContent<PathResponses<paths[Path][Method]>[Status]>, MediaType>;
151-
};
151+
[Method in keyof Partial<paths[Path]>]: MockedResponse<PathResponses<paths[Path][Method]>>;
152152
};
153153
});
154154
```

0 commit comments

Comments
 (0)