Skip to content

@j0nathan-ll0yd/testing ​

Lambda context mocks, entity mocks, event fixtures, and auth mocks for Vitest.

The package root exports the helpers below. Deeper APIs live at subpath imports: ./lambda-mocks, ./entity-mocks, ./aws-mocks, ./fixtures, ./auth-mocks, ./integration, and ./vitest-setup.

Vitest Setup ​

Add the setup file to your Vitest config. It auto-mocks every @j0nathan-ll0yd/observability export, so tests never need to stub the logger, metrics, or tracer by hand.

typescript
// vitest.config.ts
export default defineConfig({
  test: { setupFiles: ["@j0nathan-ll0yd/testing/vitest-setup"] },
});

Lambda Mocks ​

createMockContext(overrides?) ​

Build a Lambda Context with realistic defaults. Override any field.

typescript
import { createMockContext } from "@j0nathan-ll0yd/testing";

const context = createMockContext({
  functionName: "ListFiles",
  getRemainingTimeInMillis: () => 5000,
});

createMockApiEvent(overrides?) ​

Build an APIGatewayProxyEvent. Supply only the parts the handler reads.

typescript
import { createMockApiEvent } from "@j0nathan-ll0yd/testing";

const event = createMockApiEvent({
  httpMethod: "POST",
  path: "/files",
  headers: { Authorization: "Bearer test-token" },
  body: JSON.stringify({ fileId: "abc" }),
});

createObservabilityMock() ​

Return a ready-made mock module for @j0nathan-ll0yd/observability, for tests that need to assert on log or metric calls rather than merely silence them.

typescript
import { createObservabilityMock } from "@j0nathan-ll0yd/testing";

vi.mock("@j0nathan-ll0yd/observability", () => createObservabilityMock());

Entity Mocks ​

Mock a query module without restating its shape in every test file. Every mock created through these helpers is registered, so one call resets or clears them all.

createEntityMock(methods) ​

Build a mock from a list of method names.

typescript
import { createEntityMock } from "@j0nathan-ll0yd/testing";

const files = createEntityMock<typeof import("../src/db/files.js")>(["getFile", "listFiles"]);
files.getFile.mockResolvedValue({ fileId: "abc" });

createEntityMockFrom(shape) ​

Build a mock from the real module object, so a method added upstream appears in the mock automatically.

typescript
import * as fileQueries from "../src/db/files.js";
const files = createEntityMockFrom(fileQueries);

Both return a MockedEntity<T>: every function property becomes a Vitest Mock with the original signature.

resetAllEntityMocks() ​

Reset call history and implementations on every registered entity mock. Call from beforeEach.

clearAllEntityMocks() ​

Clear call history on every registered entity mock, leaving implementations in place.

Event Fixtures ​

Build valid AWS event payloads without hand-writing envelope fields.

BuilderReturns
buildSqsEvent(records)SQSEvent
buildEventBridgeEvent(options)EventBridgeEvent<TDetailType, TDetail>
buildS3Event(records)S3Event
buildScheduledEvent(options?)ScheduledEvent
buildWebSocketEvent(options)APIGatewayProxyWebsocketEventV2
typescript
import {
  buildEventBridgeEvent,
  buildS3Event,
  buildScheduledEvent,
  buildSqsEvent,
  buildWebSocketEvent,
} from "@j0nathan-ll0yd/testing";

const sqs = buildSqsEvent([{ body: { fileId: "abc" } }]); // bodies are JSON-serialized for you
const eb = buildEventBridgeEvent({ detailType: "FileUploaded", detail: { fileId: "abc" } });
const s3 = buildS3Event([{ bucket: "uploads", key: "a/b.json", size: 128 }]);
const scheduled = buildScheduledEvent({
  ruleArn: "arn:aws:events:us-east-1:123456789012:rule/daily",
});
const ws = buildWebSocketEvent({ routeKey: "$connect", connectionId: "conn-1" });

Auth Mocks ​

createAuthMock(options?) ​

Return a Better Auth double exposing api.getSession, api.signInSocial, api.revokeSession, and handler. Pass { session } to preset what getSession resolves to; pass { session: null } for the unauthenticated case.

typescript
import { createAuthMock, createSessionResult } from "@j0nathan-ll0yd/testing";

const auth = createAuthMock({ session: createSessionResult() });

createSessionResult(overrides?) ​

Build a SessionResult with a valid user and session. Accepts partial user and session overrides.

createUserDetails(overrides?) ​

Build a UserDetails object on its own, for tests that need the user but not a session.

Integration Timeouts ​

TIMEOUTS ​

Named timeout budgets in milliseconds, shared by every integration suite so no test invents its own number. Each value is larger under CI, where runners are slower.

typescript
import { TIMEOUTS } from "@j0nathan-ll0yd/testing";

it(
  "delivers the event",
  async () => {
    // ...
  },
  TIMEOUTS.eventDelivery,
);

Keys: serviceReady, eventBridgeReady, sqsMessage, sqsMultipleMessages, schemaCreation, dbConnection, eventDelivery, snsOperation, s3Operation, singleTest, e2eTest, hookTimeout.