# Test without API keys

Exercise your application's failure paths with deterministic mock outcomes.

Canonical: https://searchsdk.dev/docs/guides/testing
Markdown: https://searchsdk.dev/docs/guides/testing.md

<a id="fallback-fixture"></a>

## Assert fallback behavior

> **TypeScript reference**
> The API names, code and policy behavior in this article describe the TypeScript SDK. See [your language guide](https://searchsdk.dev/docs/sdks) for its supported surface and limits.

**fallback.test.ts · Node**

```typescript
import assert from 'node:assert/strict';
import { createSearch } from '@belweave/search-sdk';
import { createMockProvider } from '@belweave/search-sdk/testing';

const primary = createMockProvider({
  id: 'primary',
  outcomes: [{ type: 'error', code: 'rate_limit', retryAfterMs: 2_000 }],
});
const backup = createMockProvider({ id: 'backup' });
const client = createSearch({ provider: primary, fallback: [backup] });
const response = await client.web.search({ query: 'search interfaces' });

assert.equal(response.provider, 'backup');
assert.equal(response.attempts.length, 2);
assert.equal(response.warnings[0]?.code, 'fallback_used');
assert.equal(primary.calls.length, 1);
assert.equal(backup.calls.length, 1);
```

Each mock has an independent outcome queue and call history. Outcomes are reserved in invocation order, even if concurrent calls complete in a different order. An exhausted explicit queue returns `configuration`.

<a id="fixture-behavior"></a>

## Understand fixture behavior

- Without an outcome queue, the default success fixture repeats.
- A success outcome accepts `results`, `usage`, and `delayMs`. Omit provenance; the mock adds it.
- An error outcome accepts `code`, optional `status`, `retryAfterMs`, and `delayMs`.
- The mock implements hostname filtering and output limits. Timestamps reflect the actual test clock.

<a id="evidence"></a>

## Keep evidence levels separate

| Check | What it can establish |
| --- | --- |
| Application mock | Your consumer's state and error handling. |
| Injected HTTP fixture | Expected request mapping and response validation. |
| Authenticated live request | Behavior of a particular provider request at a particular time. |
| Quality evaluation | Usefulness against a dated query set and explicit rubric. |

Passing fixture tests does not establish live key validity, production availability, billing correctness, or a provider quality ranking.
