Skip to content

Commit a6122f9

Browse files
authored
Merge branch 'master' into support-node-21
2 parents 0ae33b6 + 42675f5 commit a6122f9

2 files changed

Lines changed: 56 additions & 44 deletions

File tree

README.md

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,18 @@ Start your API server with I/O schema validation and custom middlewares in minut
4646
6. [File uploads](#file-uploads)
4747
7. [Serving static files](#serving-static-files)
4848
8. [Connect to your own express app](#connect-to-your-own-express-app)
49+
9. [Testing endpoints](#testing-endpoints)
4950
6. [Special needs](#special-needs)
5051
1. [Different responses for different status codes](#different-responses-for-different-status-codes)
5152
2. [Array response](#array-response) for migrating legacy APIs
5253
3. [Headers as input source](#headers-as-input-source)
5354
4. [Accepting raw data](#accepting-raw-data)
5455
5. [Resources cleanup](#resources-cleanup)
56+
6. [Subscriptions](#subscriptions)
5557
7. [Integration and Documentation](#integration-and-documentation)
5658
1. [Generating a Frontend Client](#generating-a-frontend-client)
5759
2. [Creating a documentation](#creating-a-documentation)
5860
3. [Tagging the endpoints](#tagging-the-endpoints)
59-
4. [How to test endpoints](#how-to-test-endpoints)
6061
8. [Caveats](#caveats)
6162
1. [Coercive schema of Zod](#coercive-schema-of-zod)
6263
2. [Excessive properties in endpoint output](#excessive-properties-in-endpoint-output)
@@ -887,6 +888,46 @@ to your custom express app.
887888
Besides that, if you're looking to include additional request parsers, or a middleware that establishes its own routes,
888889
then consider using the `beforeRouting` [option in config instead](#using-native-express-middlewares).
889890

891+
## Testing endpoints
892+
893+
The way to test endpoints is to mock the request, response, and logger objects, invoke the `execute()` method, and
894+
assert the expectations for calls of certain mocked methods. The library provides a special method `testEndpoint` that
895+
makes mocking easier. It requires you either to install `jest` (with `@types/jest`) or `vitest`
896+
(detects automatically), or to specify the `fnMethod` property assigned with a function mocking method of your testing
897+
framework, which can also be `node:test` module of most modern Node.js versions.
898+
However, in order to have proper mocking types in your own tests, you also need to specify `MockOverrides` once in your
899+
tests excplicitly, so the tests should look this way:
900+
901+
```typescript
902+
import { testEndpoint } from "express-zod-api";
903+
904+
// place it once anywhere in your tests
905+
declare module "express-zod-api" {
906+
interface MockOverrides extends jest.Mock {} // or Mock from vitest
907+
}
908+
909+
test("should respond successfully", async () => {
910+
const { responseMock, loggerMock } = await testEndpoint({
911+
endpoint: yourEndpoint,
912+
requestProps: {
913+
method: "POST", // default: GET
914+
body: {}, // incoming data as if after parsing (JSON)
915+
},
916+
// fnMethod — for testing frameworks other than jest or vitest
917+
// responseProps, configProps, loggerProps
918+
});
919+
expect(loggerMock.error).toHaveBeenCalledTimes(0);
920+
expect(responseMock.status).toHaveBeenCalledWith(200);
921+
expect(responseMock.json).toHaveBeenCalledWith({
922+
status: "success",
923+
data: {},
924+
});
925+
});
926+
```
927+
928+
_This method is optimized for the `defaultResultHandler`. With the flexibility to customize, you can add additional
929+
properties as needed._
930+
890931
# Special needs
891932

892933
## Different responses for different status codes
@@ -1022,6 +1063,17 @@ const dbEquippedFactory = new EndpointsFactory(
10221063
).addMiddleware(dbProvider);
10231064
```
10241065

1066+
## Subscriptions
1067+
1068+
If you want the user of a client application to be able to subscribe to subsequent updates initiated by the server, the
1069+
capabilities of this library and the HTTP protocol itself would not be enough in this case. I have developed an
1070+
additional pluggable library, [Zod Sockets](https://github.com/RobinTail/zod-sockets), which has similar principles and
1071+
capabilities, but uses the websocket transport and Socket.IO protocol for that purpose. Check out an example of the
1072+
synergy between two libraries on handling the incoming `subscribe` and `unsubscribe` events in order to emit
1073+
(broadcast) the `time` event every second with a current time in its payload:
1074+
1075+
https://github.com/RobinTail/zod-sockets#subscriptions
1076+
10251077
# Integration and Documentation
10261078

10271079
## Generating a Frontend Client
@@ -1145,46 +1197,6 @@ const exampleEndpoint = taggedEndpointsFactory.build({
11451197
});
11461198
```
11471199

1148-
## How to test endpoints
1149-
1150-
The way to test endpoints is to mock the request, response, and logger objects, invoke the `execute()` method, and
1151-
assert the expectations for calls of certain mocked methods. The library provides a special method `testEndpoint` that
1152-
makes mocking easier. It requires you either to install `jest` (with `@types/jest`) or `vitest`
1153-
(detects automatically), or to specify the `fnMethod` property assigned with a function mocking method of your testing
1154-
framework, which can also be `node:test` module of most modern Node.js versions.
1155-
However, in order to have proper mocking types in your own tests, you also need to specify `MockOverrides` once in your
1156-
tests excplicitly, so the tests should look this way:
1157-
1158-
```typescript
1159-
import { testEndpoint } from "express-zod-api";
1160-
1161-
// place it once anywhere in your tests
1162-
declare module "express-zod-api" {
1163-
interface MockOverrides extends jest.Mock {} // or Mock from vitest
1164-
}
1165-
1166-
test("should respond successfully", async () => {
1167-
const { responseMock, loggerMock } = await testEndpoint({
1168-
endpoint: yourEndpoint,
1169-
requestProps: {
1170-
method: "POST", // default: GET
1171-
body: {}, // incoming data as if after parsing (JSON)
1172-
},
1173-
// fnMethod — for testing frameworks other than jest or vitest
1174-
// responseProps, configProps, loggerProps
1175-
});
1176-
expect(loggerMock.error).toHaveBeenCalledTimes(0);
1177-
expect(responseMock.status).toHaveBeenCalledWith(200);
1178-
expect(responseMock.json).toHaveBeenCalledWith({
1179-
status: "success",
1180-
data: {},
1181-
});
1182-
});
1183-
```
1184-
1185-
_This method is optimized for the `defaultResultHandler`. With the flexibility to customize, you can add additional
1186-
properties as needed._
1187-
11881200
# Caveats
11891201

11901202
There are some well-known issues and limitations, or third party bugs that cannot be fixed in the usual way, but you

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4765,6 +4765,6 @@ yocto-queue@^1.0.0:
47654765
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==
47664766

47674767
zod@^3.23.0:
4768-
version "3.23.3"
4769-
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.3.tgz#eeb068f83acb55310174673dee631dfa0be5510d"
4770-
integrity sha512-tPvq1B/2Yu/dh2uAIH2/BhUlUeLIUvAjr6dpL/75I0pCYefHgjhXk1o1Kob3kTU8C7yU1j396jFHlsVWFi9ogg==
4768+
version "3.23.4"
4769+
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.4.tgz#c63805b2f39e10d4ab3d55eb3c8cdb472c79dfb1"
4770+
integrity sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw==

0 commit comments

Comments
 (0)