Testing Strategy & Mocking
Relevant source files
The following files were used as context for generating this wiki page:
The Resend Node.js SDK employs a dual testing strategy. It combines unit tests using mocked HTTP responses with integration tests that record actual API traffic. This approach ensures that the client correctly formats requests, handles diverse API responses, and propagates configuration options like headers and abort signals.
Unit tests verify individual module logic and error handling without making network calls. Integration tests validate the end-to-end flow between the SDK and the Resend API by persisting request-response cycles.
Mocking Framework and Utilities
The project uses vitest and vitest-fetch-mock to intercept network requests during unit tests. Centralized utilities in src/test-utils/mock-fetch.ts provide standardized helpers for simulating successful and failed API responses.
Fetch Mocking Architecture
The SDK initializes a fetch mocker that enables global mocks before tests run. Individual test suites reset these mocks between cases to ensure isolation.
The diagram shows how tests interact with fetch mocking utilities to simulate API responses.
Sources: src/templates/templates.spec.ts:18-20, src/test-utils/mock-fetch.ts
Mocking Helpers
The following table summarizes the primary helpers used to control fetch behavior:
| Function | Purpose | Default Status |
|---|---|---|
mockSuccessResponse | Returns a successful JSON data object | 200 |
mockSuccessWithStatusCode | Returns success with a specific code (e.g., 201, 202) | Variable |
mockErrorResponse | Returns a structured ErrorResponse object | 400 |
Sources: src/test-utils/mock-fetch.ts, src/batch/batch.spec.ts:15-16
Unit Testing Patterns
Unit tests focus on payload transformation, endpoint construction, and response parsing.
Template and React Mocking
For features involving React components, such as email templates, the SDK mocks the @react-email/render module. This allows tests to verify that React elements transform into HTML strings before the SDK sends them to the API.
The sequence diagram illustrates the flow of mocking React rendering during template creation tests.
Sources: src/templates/templates.spec.ts:22-25, src/templates/templates.spec.ts:127-133
Validation and Error Handling
Tests simulate API validation failures to confirm the SDK returns structured error objects. Common scenarios include missing_required_field, not_found, and validation_error.
- Missing Fields: Tests pass empty strings to verify 422 status handling.
- Resource Not Found: Tests use invalid IDs to verify 404 status handling.
- Chained Failures: Tests ensure that if an initial request fails (e.g., 429 Rate Limit), subsequent chained methods like
.publish()return the original error without attempting further network calls.
Sources: src/api-keys/api-keys.spec.ts:60-65, src/templates/templates.spec.ts:400-410, src/automations/automations.spec.ts:85-90
Integration Testing with Polly.js
Integration tests verify the SDK against the live Resend API. The project uses @pollyjs/core to record these interactions and play them back in subsequent test runs.
Polly Setup
Integration suites use a setupPolly helper. This utility configures the Polly instance to record traffic when the RESEND_API_KEY environment variable is present. If the key is missing, Polly operates in replay mode using existing recordings.
The flow represents the logic for switching between recording and replaying HTTP traffic in integration tests.
Sources: src/test-utils/polly-setup.ts, src/contacts/contacts.integration.spec.ts:12-16
Resource Lifecycle Testing
Integration tests typically follow a "Create-Verify-Remove" pattern to keep the test environment clean.
- Create a temporary resource (e.g., a Segment).
- Use that resource ID to test another feature (e.g., adding a Contact to that Segment).
- Delete all created resources in a
finallyblock orafterEachhook.
Sources: src/contacts/contacts.integration.spec.ts:24-65, src/segments/segments.integration.spec.ts:20-30
Request Options Verification
A dedicated test suite in src/request-options.spec.ts ensures that all public resource methods correctly handle RequestOptions.
Header and Signal Propagation
The SDK must forward custom headers and AbortSignal instances to the underlying fetch call. Tests verify this by:
- Passing an
AbortController.signaland asserting it reaches the fetch init object. - Passing custom headers (e.g.,
X-Trace-Id) and checking the fetch request headers.
Sources: src/request-options.spec.ts:314-328
Idempotency Key Handling
Methods that modify data (POST, PATCH, DELETE) support an idempotencyKey. Tests verify that when this key is provided in the options, the SDK includes an Idempotency-Key header in the HTTP request.
Sources: src/batch/batch.spec.ts:145-165, src/inboxes/drafts/drafts.spec.ts:175-185
Batch Validation Modes
Batch operations include specific tests for the x-batch-validation header. Tests ensure the SDK defaults to strict but allows overrides to permissive via either explicit options or custom headers.
Sources: src/batch/batch.spec.ts:42-60
Summary of Testing Tools
| Tool | Usage |
|---|---|
| Vitest | Primary test runner and assertion library. |
| vitest-fetch-mock | Mocks the global fetch API for unit tests. |
| Polly.js | Records and replays HTTP interactions for integration tests. |
| React Email Render | Mocked to test HTML generation from React components. |
Sources: src/templates/templates.spec.ts:1-15, src/test-utils/polly-setup.ts