Explore the directory
Skip to article
Testing & mocks

Testing & mocks

Keep most integration tests local, predictable, and free of side effects. Use a smaller set of explicit live checks to verify the real provider contract.

On this page

Test your application boundary

Inject the operation your product needs instead of constructing a live SDK client inside business logic. A deterministic fake lets you verify the inputs and outcomes that matter without imitating every internal detail of a provider library.

email.ts · illustrative app-owned workflow and fake
type EmailInput = { to: string; subject: string };
type EmailSender = {
  send(input: EmailInput): Promise<{ id: string }>;
};

export async function sendWelcome(
  sender: EmailSender,
  recipient: string,
) {
  return sender.send({
    to: recipient.trim(),
    subject: 'Welcome',
  });
}

export function createFakeEmailSender() {
  const calls: EmailInput[] = [];
  const sender: EmailSender = {
    async send(input) {
      calls.push({ ...input });
      return { id: 'email_fixture_001' };
    },
  };
  return { sender, calls };
}

Make fixtures deterministic

Use fixed identifiers and explicit error fixtures. Inject clocks, ID generators, and random-number sources when the behavior depends on them. Create a fresh fake for each test so execution order cannot change the result.

Workflow test · node:test + app-owned fake
import test from 'node:test';
import assert from 'node:assert/strict';
import { createFakeEmailSender, sendWelcome } from './email';

test('welcome sends to the normalized recipient', async () => {
  const { sender, calls } = createFakeEmailSender();
  const result = await sendWelcome(
    sender,
    '  reader@example.com  ',
  );

  assert.equal(result.id, 'email_fixture_001');
  assert.deepEqual(calls, [{
    to: 'reader@example.com',
    subject: 'Welcome',
  }]);
});

The example uses the built-in Node.js test runner. Run TypeScript through your project's configured test toolchain. The fake records what the welcome workflow actually sends, so the test checks recipient normalization and the product's chosen subject.

Cover the difficult paths

FixtureBehavior to verify
Invalid inputValidation fails before a provider request is made.
Unsupported capabilityNo empty-success response or accidental fallback.
Rate limitThe retry policy respects its deadline and attempt budget.
Timeout after submissionA side effect is not blindly repeated.
Partial resultFailed items remain visible alongside successful items.
Privacy restrictionNo data is sent to an unapproved fallback provider.

Separate live contract checks

Use dedicated credentials and test data, set a spending limit, and clean up created records. Require an explicit opt-in for tests that contact a provider. Never let a missing fixture or environment variable quietly turn a local test into a live request.

SDK SDK is an independent discovery hub. Provider examples link to official documentation. App-owned examples are illustrative patterns you can adapt.