# Testing (/testing)



`@usebutr/testing` provides deterministic test doubles. Install it as a dev
dependency:

<CodeBlockTabs defaultValue="npm" groupId="package-manager">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npm install --save-dev @usebutr/testing
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm add --save-dev @usebutr/testing
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn add --dev @usebutr/testing
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun add --dev @usebutr/testing
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## `createFakeAdapter(options?): WalletAdapter` [#createfakeadapteroptions-walletadapter]

Every method resolves to a deterministic stub. Override individual methods
after construction to inject failure modes.

```ts
import { createFakeAdapter } from "@usebutr/testing";

const adapter = createFakeAdapter({ id: "metamask" });
adapter.connect = () => Promise.reject(new Error("user rejected"));
```

### `FakeAdapterOptions` [#fakeadapteroptions]

| Field           | Default                                 |
| --------------- | --------------------------------------- |
| `id`            | `"fake"`                                |
| `name`          | `"Fake Wallet"`                         |
| `chainPlatform` | `"evm"`                                 |
| `accounts`      | `[]`                                    |
| `icon`          | —                                       |
| `capabilities`  | all `true` (merged over your overrides) |

Stub returns include: `getAccount()` → first account or `null`; `sendTx()` →
`"0xfakehash"`; `signMessage(msg)` → `{ signature: msg, signedMessage: msg }`;
`getBalance()` → `{ decimals: 18, formatted: "0", symbol: "ETH" | "SOL", value: 0n }`;
`subscribe()` → no-op unsubscribe.

Wire it through `createConnector` to test the store or React hooks:

```ts
const adapter = createFakeAdapter({ id: "fake" });
const config: WalletManagerConfig = {
  connectors: [{ id: "fake", name: "Fake", chainPlatform: "evm" }],
  createConnector: (id) => (id === "fake" ? adapter : null),
};
```

## `createFakePersistence(seed?): WalletPersistence` [#createfakepersistenceseed-walletpersistence]

In-memory `WalletPersistence` mirroring `WalletStorage`'s shape — no
`localStorage`, no cookies. Reads/writes resolve synchronously (wrapped in
`Promise.resolve`).

```ts
import { createFakePersistence } from "@usebutr/testing";

const persistence = createFakePersistence({
  activeConnectorId: "fake",
  pool: {
    fake: {
      account: seedAccount,
      accounts: [seedAccount],
      chainPlatform: "evm",
      connectorId: "fake",
    },
  },
  selection: { evm: "fake" },
  userDisconnected: true,
});
```

`FakePersistenceSeed` fields: `pool`, `selection`, `activeConnectorId`,
`userDisconnected`. Pass it as the `storage` in
[`WalletManagerConfig`](/guides/lifecycle-callbacks) to test hydration and
persistence without side effects. `clearAll()` resets everything.

<Callout type="info">
  **Source:** `packages/testing/src` (`fake-adapter.ts`, `fake-persistence.ts`, and their
  `__tests__`) in the [butr
  repository](https://github.com/pedroapfilho/usebutr/tree/main/packages/testing).
</Callout>
