vitest-websocket-mock 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -12
- package/dist/index.d.ts +8 -9
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# vitest-websocket-mock
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/js/vitest-websocket-mock)
|
|
4
4
|
[](https://github.com/akiomik/vitest-websocket-mock/actions)
|
|
5
5
|
[](https://codecov.io/gh/akiomik/vitest-websocket-mock)
|
|
6
6
|
|
|
7
|
-
A set of utilities and Vitest matchers to help testing complex websocket interactions
|
|
8
|
-
|
|
7
|
+
A set of utilities and Vitest matchers to help testing complex websocket interactions:
|
|
8
|
+
mock websocket servers, wait for connections and messages, and assert on them
|
|
9
|
+
with dedicated matchers.
|
|
10
|
+
|
|
11
|
+
Originally forked from [romgain/jest-websocket-mock](https://github.com/romgain/jest-websocket-mock),
|
|
12
|
+
and since developed independently as a Vitest-first library.
|
|
9
13
|
|
|
10
14
|
**Examples:**
|
|
11
15
|
Several examples are provided in the [examples folder](https://github.com/akiomik/vitest-websocket-mock/blob/main/examples/).
|
|
@@ -15,8 +19,31 @@ In particular:
|
|
|
15
19
|
- [testing a component using the saga above](https://github.com/akiomik/vitest-websocket-mock/blob/main/examples/redux-saga/src/__tests__/App.test.tsx)
|
|
16
20
|
- [testing a component that manages a websocket connection using react hooks](https://github.com/akiomik/vitest-websocket-mock/blob/main/examples/hooks/src/App.test.tsx)
|
|
17
21
|
|
|
22
|
+
## When to use this vs. MSW
|
|
23
|
+
|
|
24
|
+
[Vitest recommends](https://vitest.dev/guide/mocking/requests) [Mock Service Worker (MSW)](https://mswjs.io)
|
|
25
|
+
for mocking network requests, and MSW has first-class
|
|
26
|
+
[WebSocket support](https://mswjs.io/docs/websocket/). The two address different
|
|
27
|
+
layers of the problem:
|
|
28
|
+
|
|
29
|
+
- **MSW** provides declarative, network-level mocking (`ws.link()` handlers).
|
|
30
|
+
It shines when you want to share handlers between your app, Storybook, and
|
|
31
|
+
tests, or when you also need to mock HTTP or GraphQL.
|
|
32
|
+
- **`vitest-websocket-mock`** provides imperative test-flow ergonomics that MSW
|
|
33
|
+
does not: a `WS` mock-server object, `await server.connected`, a synchronous
|
|
34
|
+
record of received messages in `server.messages`, and custom matchers such as
|
|
35
|
+
`.toReceiveMessage` and `.toHaveReceivedMessages`.
|
|
36
|
+
|
|
37
|
+
If your test reads best as a step-by-step conversation with a mock server
|
|
38
|
+
("wait for the connection, assert on the next message, reply, assert again"),
|
|
39
|
+
this library is the better fit. Running this library on top of MSW's
|
|
40
|
+
interceptor, which would make the two complementary rather than alternatives,
|
|
41
|
+
is being explored in [#77](https://github.com/akiomik/vitest-websocket-mock/issues/77).
|
|
42
|
+
|
|
18
43
|
## Install
|
|
19
44
|
|
|
45
|
+
`vitest-websocket-mock` requires Vitest 5 as a peer dependency.
|
|
46
|
+
|
|
20
47
|
```bash
|
|
21
48
|
npm install -D vitest-websocket-mock
|
|
22
49
|
```
|
|
@@ -65,7 +92,7 @@ const server = new WS('ws://localhost:1234', { jsonProtocol: true });
|
|
|
65
92
|
server.send({ type: 'GREETING', payload: 'hello' });
|
|
66
93
|
```
|
|
67
94
|
|
|
68
|
-
- The `mock-
|
|
95
|
+
- The [`mock-socket`](https://github.com/thoov/mock-socket) server options `verifyClient` and `selectProtocol` are directly passed through to the underlying mock server's constructor.
|
|
69
96
|
|
|
70
97
|
### Attributes of a `WS` instance
|
|
71
98
|
|
|
@@ -98,8 +125,9 @@ A `WS` instance has the following attributes:
|
|
|
98
125
|
|
|
99
126
|
## Run assertions on received messages
|
|
100
127
|
|
|
101
|
-
`vitest-websocket-mock` registers custom
|
|
102
|
-
on received messages easier
|
|
128
|
+
`vitest-websocket-mock` registers custom Vitest matchers to make assertions
|
|
129
|
+
on received messages easier. They are registered automatically when
|
|
130
|
+
`vitest-websocket-mock` is imported, so no extra setup file is needed:
|
|
103
131
|
|
|
104
132
|
- `.toReceiveMessage`: async matcher that waits for the next message received
|
|
105
133
|
by the mock websocket server, and asserts its content. It will time out
|
|
@@ -329,6 +357,19 @@ You can work around this by installing the setImmediate shim from
|
|
|
329
357
|
[https://github.com/YuzuJS/setImmediate](https://github.com/YuzuJS/setImmediate) and
|
|
330
358
|
adding `require('setimmediate');` to your `setupTests.js`.
|
|
331
359
|
|
|
360
|
+
### The custom matchers are not recognized by TypeScript
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
Property 'toReceiveMessage' does not exist on type 'Assertion<void, WS>'.
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The matchers are contributed with [module augmentation][augmentation], which
|
|
367
|
+
only merges into the copy of `vitest` the augmentation resolves to. Deduplicate
|
|
368
|
+
`vitest` if your project resolves more than one, for example a monorepo where a
|
|
369
|
+
nested package pins its own.
|
|
370
|
+
|
|
371
|
+
[augmentation]: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
|
|
372
|
+
|
|
332
373
|
## Testing React applications
|
|
333
374
|
|
|
334
375
|
When testing React applications, `vitest-websocket-mock` will look for
|
|
@@ -377,9 +418,3 @@ the `mock-socket` library that `vitest-websocket-mock` uses under the hood only
|
|
|
377
418
|
implements the browser API.
|
|
378
419
|
As a result, `vitest-websocket-mock` will only work with the `ws` library if you
|
|
379
420
|
restrict yourself to the browser APIs!
|
|
380
|
-
|
|
381
|
-
## Examples
|
|
382
|
-
|
|
383
|
-
For a real life example, see the
|
|
384
|
-
[examples directory](https://github.com/akiomik/vitest-websocket-mock/tree/main/examples),
|
|
385
|
-
and in particular the saga tests.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Matcher } from "vitest";
|
|
1
2
|
import { Client, CloseOptions, Server, ServerOptions } from "mock-socket";
|
|
2
|
-
import { RawMatcherFn } from "@vitest/expect";
|
|
3
3
|
//#region src/derivers/deriveToHaveReceivedMessage.d.ts
|
|
4
|
-
declare function deriveToHaveReceivedMessage(name: string, fn:
|
|
4
|
+
declare function deriveToHaveReceivedMessage(name: string, fn: Matcher): Matcher;
|
|
5
5
|
//#endregion
|
|
6
6
|
//#region src/derivers/deriveToReceiveMessage.d.ts
|
|
7
|
-
declare function deriveToReceiveMessage(name: string, fn:
|
|
7
|
+
declare function deriveToReceiveMessage(name: string, fn: Matcher): Matcher;
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/derivers/types.d.ts
|
|
10
10
|
/**
|
|
@@ -32,7 +32,7 @@ interface WSOptions extends ServerOptions {
|
|
|
32
32
|
jsonProtocol?: boolean;
|
|
33
33
|
}
|
|
34
34
|
type DeserializedMessage<TMessage = object> = string | TMessage;
|
|
35
|
-
|
|
35
|
+
export default class WS {
|
|
36
36
|
server: Server;
|
|
37
37
|
serializer: (deserializedMessage: DeserializedMessage) => string;
|
|
38
38
|
deserializer: (message: string) => DeserializedMessage;
|
|
@@ -54,14 +54,13 @@ declare class WS {
|
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/matchers/index.d.ts
|
|
56
56
|
interface CustomMatchers<R = unknown> {
|
|
57
|
-
toReceiveMessage<TMessage = object>(message: DeserializedMessage<TMessage>, options?: ReceiveMessageOptions): Promise<
|
|
57
|
+
toReceiveMessage<TMessage = object>(message: DeserializedMessage<TMessage>, options?: ReceiveMessageOptions): Promise<void>;
|
|
58
58
|
toHaveReceivedMessages<TMessage = object>(messages: Array<DeserializedMessage<TMessage>>): R;
|
|
59
59
|
}
|
|
60
60
|
//#endregion
|
|
61
61
|
//#region src/extend-expect.d.ts
|
|
62
|
-
declare module '
|
|
63
|
-
interface
|
|
64
|
-
interface AsymmetricMatchersContaining extends CustomMatchers {}
|
|
62
|
+
declare module 'vitest' {
|
|
63
|
+
interface Matchers<R extends void | Promise<void> = void | Promise<void>, T = unknown> extends CustomMatchers<R> {}
|
|
65
64
|
}
|
|
66
65
|
//#endregion
|
|
67
|
-
export { type ReceiveMessageOptions, WS,
|
|
66
|
+
export { type ReceiveMessageOptions, WS, deriveToHaveReceivedMessage, deriveToReceiveMessage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-websocket-mock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Mock websockets and assert complex websocket interactions with Vitest",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@biomejs/biome": "^2.5.3",
|
|
39
39
|
"@types/node": "^26.1.1",
|
|
40
|
-
"@vitest/coverage-v8": "^
|
|
41
|
-
"rimraf": "^
|
|
42
|
-
"tsdown": "^0.
|
|
40
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
41
|
+
"rimraf": "^6.1.3",
|
|
42
|
+
"tsdown": "^0.23.0",
|
|
43
43
|
"typescript": "^7.0.2",
|
|
44
44
|
"vite": "^8.1.4",
|
|
45
|
-
"vitest": "^
|
|
45
|
+
"vitest": "^5.0.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"vitest": ">=
|
|
48
|
+
"vitest": ">=5 <6"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"mock-socket": "^9.2.1"
|