or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

chai-matchers.mdcompiler-utilities.mdcontract-deployment.mdens-utilities.mdindex.mdmock-contracts.mdoptimism-provider.mdprovider-testing.md
tile.json

provider-testing.mddocs/

Provider & Testing Utilities

Core testing infrastructure for Ethereum Waffle including MockProvider for local blockchain simulation, pre-funded test accounts, fixtures for efficient test setup, and comprehensive call history tracking.

Capabilities

MockProvider

Enhanced Web3Provider designed specifically for testing, providing isolated blockchain environment with pre-funded accounts, call history tracking, and ENS support.

/**
 * Enhanced Web3Provider for testing with isolated blockchain environment
 * @param options - Configuration options for the provider
 */
class MockProvider extends providers.Web3Provider {
  constructor(options?: MockProviderOptions);
  
  /** Get array of pre-funded test wallets */
  getWallets(): Wallet[];
  
  /** Create new empty wallet without ETH balance */
  createEmptyWallet(): Wallet;
  
  /** Clear all recorded contract calls */
  clearCallHistory(): void;
  
  /** Setup ENS domain resolution for testing */
  setupENS(wallet?: Wallet): Promise<void>;
  
  /** Read-only access to all recorded contract calls */
  readonly callHistory: readonly RecordedCall[];
  
  /** ENS instance if setupENS was called */
  readonly ens: ENS | undefined;
}

interface MockProviderOptions {
  ganacheOptions: EthereumProviderOptions;
}

interface RecordedCall {
  readonly address: string | undefined;
  readonly data: string;
}

Usage Examples:

import { MockProvider } from "ethereum-waffle";

// Create provider with default settings
const provider = new MockProvider();
const [wallet, otherWallet] = provider.getWallets();

// Create provider with custom ganache options
const customProvider = new MockProvider({
  ganacheOptions: {
    gasLimit: 8000000,
    gasPrice: 20000000000
  }
});

// Track contract calls
const contract = await deployContract(wallet, contractJson);
await contract.someFunction();

console.log(provider.callHistory); // Array of RecordedCall objects

// Setup ENS for testing
await provider.setupENS(wallet);
const address = await provider.resolveName('test.eth');

Test Fixtures

Efficient test setup system with automatic blockchain snapshotting and restoration, enabling fast test execution by reusing common setup scenarios.

/**
 * Function type for test fixtures that setup testing environment
 * @param wallets - Array of funded wallets for testing
 * @param provider - MockProvider instance
 * @returns Promise resolving to fixture state
 */
type Fixture<T> = (wallets: Wallet[], provider: MockProvider) => Promise<T>;

/**
 * Load a fixture with automatic snapshotting for test isolation
 * @param fixture - Fixture function to execute and cache
 * @returns Promise resolving to fixture result
 */
function loadFixture<T>(fixture: Fixture<T>): Promise<T>;

/**
 * Create custom fixture loader with specific wallets and provider
 * @param overrideWallets - Custom wallets to use instead of defaults
 * @param overrideProvider - Custom provider to use instead of default
 * @returns Fixture loader function
 */
function createFixtureLoader(
  overrideWallets?: Wallet[], 
  overrideProvider?: MockProvider
): <T>(fixture: Fixture<T>) => Promise<T>;

Usage Examples:

import { loadFixture, MockProvider } from "ethereum-waffle";

// Define a fixture
const myFixture: Fixture<{token: Contract, wallet: Wallet}> = async (wallets, provider) => {
  const [wallet] = wallets;
  const token = await deployContract(wallet, ERC20Json, ["Test Token", "TEST"]);
  await token.mint(wallet.address, 1000);
  return { token, wallet };
};

// Use fixture in tests - automatically cached and snapshot restored
it("should transfer tokens", async () => {
  const { token, wallet } = await loadFixture(myFixture);
  // Test logic here - fresh state each time
});

// Create custom fixture loader
const customLoader = createFixtureLoader(customWallets, customProvider);
const result = await customLoader(myFixture);

Default Test Accounts

Pre-configured test accounts with deterministic private keys and substantial ETH balances for consistent testing.

/**
 * Array of 10 pre-funded test accounts with deterministic private keys
 * Each account has balance: '0x1ED09BEAD87C0378D8E6400000000' (10^34 wei)
 */
const defaultAccounts: Array<{
  balance: string;
  secretKey: string;
}>;

Usage Examples:

import { defaultAccounts, MockProvider } from "ethereum-waffle";

// Access account private keys
const privateKey = defaultAccounts[0].secretKey;
const wallet = new Wallet(privateKey);

// Check account balance (same for all 10 accounts)
console.log(defaultAccounts[0].balance); // '0x1ED09BEAD87C0378D8E6400000000'

// Use with custom provider
const provider = new MockProvider();
const wallets = provider.getWallets(); // Uses defaultAccounts automatically

Call History Tracking

System for recording and analyzing contract function calls during testing, useful for verifying interaction patterns and debugging.

/**
 * Tracks and manages contract call history
 */
class CallHistory {
  /** Clear all recorded calls */
  clear(): void;
  
  /** Get array of all recorded calls */
  getCalls(): RecordedCall[];
  
  /** Wrap provider to record calls */
  record(provider: Provider): Provider;
}

Usage Examples:

import { MockProvider } from "ethereum-waffle";

const provider = new MockProvider();
const [wallet] = provider.getWallets();

// Deploy and interact with contract
const contract = await deployContract(wallet, contractJson);
await contract.setValue(42);
await contract.getValue();

// Check call history
console.log(provider.callHistory.length); // 2
console.log(provider.callHistory[0].data); // Encoded setValue call data

// Clear history for next test
provider.clearCallHistory();

Revert String Utilities

Utilities for extracting and handling revert reasons from failed transactions, providing better debugging information during testing.

/**
 * Extract revert reason string from call revert error
 * @param callRevertError - Error object from failed contract call
 * @returns Decoded revert reason string
 */
function decodeRevertString(callRevertError: any): string;

/**
 * Append revert string to transaction receipt for debugging
 * @param etherProvider - Web3Provider instance
 * @param receipt - Transaction receipt to enhance
 */
function appendRevertString(etherProvider: providers.Web3Provider, receipt: any): Promise<void>;

/**
 * Inject revert string decoding capabilities into provider
 * @param provider - Provider to enhance with revert string support
 * @returns Enhanced provider with revert string decoding
 */
function injectRevertString(provider: Provider): Provider;

Usage Examples:

import { decodeRevertString, MockProvider } from "ethereum-waffle";

const provider = new MockProvider();
const [wallet] = provider.getWallets();

try {
  await contract.requireSomething();
} catch (error) {
  const revertReason = decodeRevertString(error);
  console.log("Revert reason:", revertReason); // "Something is required"
}

// Enhance provider with automatic revert string extraction
const enhancedProvider = injectRevertString(provider);

Custom Fixture Loader

Factory function for creating custom fixture loaders with specific wallets and providers, enabling advanced test setup scenarios.

/**
 * Create custom fixture loader with specific wallets and provider
 * @param overrideWallets - Custom wallets to use instead of defaults
 * @param overrideProvider - Custom provider to use instead of default
 * @returns Fixture loader function
 */
function createFixtureLoader(
  overrideWallets?: Wallet[], 
  overrideProvider?: MockProvider
): <T>(fixture: Fixture<T>) => Promise<T>;

Usage Examples:

import { createFixtureLoader, MockProvider } from "ethereum-waffle";

// Create custom wallets
const customWallets = [
  new Wallet("0x1234..."),
  new Wallet("0x5678...")
];

// Create custom provider with specific options
const customProvider = new MockProvider({
  ganacheOptions: {
    gasLimit: 8000000,
    accounts: customWallets.map(w => ({
      balance: "0x1000000000000000000",
      secretKey: w.privateKey
    }))
  }
});

// Create custom fixture loader
const loadCustomFixture = createFixtureLoader(customWallets, customProvider);

// Use in tests
const myFixture = async (wallets, provider) => {
  const [owner, user] = wallets;
  const contract = await deployContract(owner, ContractJson);
  return { contract, owner, user };
};

const { contract, owner, user } = await loadCustomFixture(myFixture);

Revert String Utilities

Enhanced error handling utilities for extracting and analyzing revert reasons from failed transactions.

/**
 * Extract revert reason string from call revert error
 * @param callRevertError - Error object from failed contract call
 * @returns Decoded revert reason string
 */
function decodeRevertString(callRevertError: any): string;

/**
 * Append revert string to transaction receipt for debugging
 * @param etherProvider - Web3Provider instance
 * @param receipt - Transaction receipt to enhance
 * @returns Promise that resolves when revert string is appended
 */
function appendRevertString(etherProvider: providers.Web3Provider, receipt: any): Promise<void>;

/**
 * Inject revert string decoding capabilities into provider
 * @param provider - Provider to enhance with revert string support
 * @returns Enhanced provider with revert string decoding
 */
function injectRevertString(provider: Provider): Provider;

Usage Examples:

import { decodeRevertString, injectRevertString, MockProvider } from "ethereum-waffle";

const provider = new MockProvider();
const [wallet] = provider.getWallets();

// Manual revert string extraction
try {
  await contract.restrictedFunction();
} catch (error) {
  const revertReason = decodeRevertString(error);
  console.log("Transaction failed:", revertReason);
}

// Automatic revert string enhancement
const enhancedProvider = injectRevertString(provider);

// Enhanced provider automatically includes revert strings in error messages
try {
  const contract = new Contract(address, abi, enhancedProvider);
  await contract.failingFunction();
} catch (error) {
  console.log(error.message); // Includes decoded revert reason
}

TestProvider Type

Type definition for providers enhanced with wallet access, compatible with both MockProvider and other test providers.

/**
 * Provider interface with wallet access for testing
 */
type TestProvider = providers.BaseProvider & {
  /** Get array of test wallets */
  getWallets(): Wallet[];
  
  /** Get L1 fee for transaction (Optimism/L2 networks) */
  getL1Fee?(txHash: string): Promise<BigNumber>;
};

Usage Examples:

import { TestProvider, MockProvider } from "ethereum-waffle";

function setupTest(provider: TestProvider) {
  const wallets = provider.getWallets();
  // Test setup logic
}

const mockProvider = new MockProvider();
setupTest(mockProvider); // TypeScript knows MockProvider implements TestProvider