learn.sol
Week 4 • Client Testing Strategy Lite Unit And Integration

Client Testing Strategy: Lite Unit & Integration

A practical testing strategy for Solana client code: fast unit checks plus one meaningful integration path.

Step 1: 0-to-1 Theory

Primitives

  • unit test: tests pure functions without network
  • integration test: tests feature path across service + state
  • failure-path test: proves behavior under expected errors

Mental Model

Solana client bugs usually show up as:

  • wrong inputs (amounts, addresses, cluster)
  • wrong state (wallet disconnected, stale blockhash)
  • wrong expectations (sent vs confirmed)

Tests should match that reality. Start with pure functions (fast) and add one integration path (realistic).

Invariants

  1. Happy-path-only tests are not enough.
  2. Error mapping logic must be unit tested.
  3. One stable integration path must run in CI.

Quick Checks

  1. Why are failure-path tests mandatory in wallet apps?
  2. What should be mocked vs real in integration tests?

Step 2: Real-World Implementation (Code Solution)

Install test stack if needed:

pnpm add -D vitest @testing-library/react @testing-library/jest-dom jsdom

Create lib/solana/__tests__/uiTxState.test.ts:

import { describe, it, expect } from "vitest";
import { classifyTxError } from "../uiTxState";

describe("classifyTxError", () => {
  it("maps rejection", () => {
    // User rejection should be treated as a normal user action, not a crash.
    expect(classifyTxError("User rejected request")).toBe("user-rejected");
  });

  it("maps blockhash expiry", () => {
    // Expired blockhash usually means rebuild + re-sign is required.
    expect(classifyTxError("Blockhash not found")).toBe("expired");
  });

  it("maps unknown", () => {
    // Unknown errors are expected; we still want deterministic UX behavior.
    expect(classifyTxError("strange failure")).toBe("unknown");
  });
});

Create components/solana/__tests__/TxActionCard.test.tsx:

import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { TxActionCard } from "../TxActionCard";

describe("TxActionCard", () => {
  it("renders default status", () => {
    // Smoke test: component renders and shows a status label.
    render(<TxActionCard />);
    expect(screen.getByText(/Status:/)).toBeTruthy();
  });
});

Add script:

{
  "scripts": {
    "test": "vitest run"
  }
}

Run:

pnpm test

Expected result:

  • unit tests verify error classification behavior.

Step 3: Mastery Test

  • Easy: what is the fastest pure function to test first?
  • Medium: where should integration tests stop (UI only vs RPC)?
  • Hard: how would you design deterministic tests for retry logic?

Sources

Solana Assistant

AI-powered documentation helper

Welcome to Solana Assistant

Ask specific questions about Solana development:

Ask specific questions for better results400px
    Client Testing Strategy: Lite Unit & Integration | learn.sol