Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .changeset/msw-request-handlers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
"@labdigital/mock-dynamodb": minor
---

Replace nock with msw request handlers (breaking)

This mock no longer runs an interceptor of its own. Instead it exposes msw
request handlers that are registered on the msw server owned by your test
suite, which avoids two libraries fighting over request interception. `msw` is
a peer dependency now.

```diff
const mddb = mockDynamoDB({ endpoint: "http://localhost:4000" });
+const server = setupServer(...mddb.getHandlers());
+server.listen();

mddb.reset();
-mddb.stop();
+server.close();
```

`start()` and `stop()` throw an error pointing at the new setup, they are
removed in 1.0. Table lifecycle actions now wait for the table to reach its
settled state before responding, so a table can be written to immediately
after `createTable()` resolves.
55 changes: 50 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
# DynamoDB Mock
This is a relatively simple wrapper around
[dynalite](https://github.com/mhart/dynalite) to make it easier to use in a test
environment.
environment. Requests are intercepted with [msw](https://mswjs.io/), so no
actual server or port is used.

[![npm](https://img.shields.io/npm/v/@labdigital/mock-dynamodb.svg)](https://www.npmjs.com/package/@labdigital/mock-dynamodb)

## Usage
```typescript
This package provides msw request handlers, the msw server itself is managed by
your own test setup. Pass the handlers to `setupServer()` so that they survive
`server.resetHandlers()`:

```typescript
import { mockDynamoDB } from "@labdigital/mock-dynamodb";
import { setupServer } from "msw/node";
import { afterAll, afterEach, beforeAll } from "vitest";

export const mddb = mockDynamoDB({ endpoint: "http://localhost:4000" });
export const server = setupServer(...mddb.getHandlers());

const mddb = mockDynamoDB({ endpoint: "http://localhost:4000" });
const client = new DynamoDB({
endpoint: "http://localhost:4000",
region: "local",
Expand All @@ -20,7 +28,44 @@ const client = new DynamoDB({
},
});

mddb.reset(); // Clear all data
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
afterEach(() => mddb.reset()); // Clear all data
afterAll(() => server.close());
```

Every `accessKeyId` gets its own store, so tests using different credentials
don't see each other's data. `reset()` clears the data of all of them.

If you need to bind to a server that is already running, use
`registerHandlers()` instead. Note that those handlers are removed again by
`server.resetHandlers()`, so they have to be registered per test:

```typescript
beforeEach(() => mddb.registerHandlers(server));
```

### Combining with other mocks
Use a single msw server for all of your mocks, running more than one server per
process is not supported by msw:

```typescript
const server = setupServer(...ctMock.getHandlers(), ...mddb.getHandlers());
```

## Migrating from 0.2.x
Version 0.3.0 replaced [nock](https://github.com/nock/nock) with msw, which
means this package no longer starts an interceptor of its own. `msw` is a peer
dependency now and has to be installed alongside it.

mddb.stop(); // Stop the server
```diff
const mddb = mockDynamoDB({ endpoint: "http://localhost:4000" });
+const server = setupServer(...mddb.getHandlers());
+server.listen();

mddb.reset();
-mddb.stop();
+server.close();
```

`start()` and `stop()` throw an error pointing at the above, they are removed
in 1.0.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,18 @@
"test:ci": "pnpm vitest run --coverage",
"tsc": "tsc"
},
"dependencies": {
"nock": "14.0.17"
"peerDependencies": {
"msw": "^2.0.0"
},
"devDependencies": {
"@aws-sdk/client-dynamodb": "3.1101.0",
"@biomejs/biome": "2.5.6",
"@changesets/cli": "2.31.1",
"@types/express": "5.0.6",
"@types/node": "^26.1.2",
"@vitest/coverage-v8": "4.1.10",
"dynalite": "4.0.0",
"msw": "2.15.0",
"tsdown": "0.22.14",
"tsx": "4.23.5",
"typescript": "7.0.2",
Expand Down
Loading
Loading