Viem 测试客户端(Test Client)核心解析 Link to heading
核心定位 Link to heading
Viem 的 Test Client 是专为本地以太坊测试节点(如 Anvil、Hardhat、Ganache)设计的交互工具,提供测试环境专属的高级操作能力,用于简化区块链应用的开发、调试和测试流程。它是连接测试节点与应用代码的桥梁,聚焦于 “测试场景构建” 和 “链上状态控制”。
核心功能 Link to heading
- 测试节点专属操作(Test Actions)
提供直接控制本地测试节点的功能,支持灵活构建测试场景:
- 区块控制:手动挖矿(
mine
)、设置区块时间(setNextBlockTimestamp
),加速交易确认流程。 - 账户模拟:临时接管任意账户(
impersonateAccount
),无需私钥即可操作目标账户,方便测试权限逻辑。 - 状态修改:直接修改账户余额(
setBalance
)、合约代码(setCode
)、存储数据(setStorageAt
),快速构建特定测试状态。 - 费用配置:自定义基础 Gas 费(
setNextBlockBaseFeePerGas
),测试不同费用策略下的交易行为。
- 区块控制:手动挖矿(
- 集成读写功能
可通过扩展(
extend
)集成公共客户端(publicActions
)和钱包客户端(walletActions
)的功能,在同一客户端中完成:- 读操作(如查询区块、合约数据);
- 写操作(如发送交易、调用合约);
- 测试操作(如挖矿、模拟账户),避免多客户端配置冗余。
核心配置与使用 Link to heading
1. 初始化测试客户端 Link to heading
通过 createTestClient
创建实例,必须指定测试节点类型(mode) 和传输层(Transport),通常搭配本地测试链(如 Foundry)使用:
import { createTestClient, http } from 'viem'
import { foundry } from 'viem/chains'
// 连接 Anvil 本地测试节点
const testClient = createTestClient({
chain: foundry, // Foundry 本地链(默认适配 Anvil)
mode: 'anvil', // 测试节点类型(支持 anvil、hardhat、ganache)
transport: http('http://localhost:8545'), // 本地节点 RPC 地址
})
2. 核心 API 示例 Link to heading
(1)基础测试操作 Link to heading
// 挖矿 1 个区块(立即确认交易)
await testClient.mine({ blocks: 1 })
// 模拟控制目标账户(无需私钥)
await testClient.impersonateAccount({ address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' })
// 修改账户余额(充值 10 ETH)
await testClient.setBalance({
address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
value: parseEther('10'), // 转换为 wei
})
// 设置下一个区块的时间
await testClient.setNextBlockTimestamp({ timestamp: 1678900000 })
(2)扩展读写功能 Link to heading
import { createTestClient, http, publicActions, walletActions } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
// 扩展公共和钱包功能,一站式处理读写和测试操作
const testClient = createTestClient({
chain: foundry,
mode: 'anvil',
transport: http(),
})
.extend(publicActions) // 增加读操作(如 getBlockNumber)
.extend(walletActions) // 增加写操作(如 sendTransaction)
// 读操作:查询最新区块号
const blockNumber = await testClient.getBlockNumber()
// 写操作:发送交易(使用本地账户)
const account = privateKeyToAccount('0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690')
const hash = await testClient.sendTransaction({
account,
to: '0x0000000000000000000000000000000000000000',
value: parseEther('1'),
})
// 测试操作:挖矿确认交易
await testClient.mine({ blocks: 1 })
关键参数说明 Link to heading
参数 | 类型 | 说明 |
---|---|---|
mode |
`anvil | hardhat |
transport |
Transport |
传输层(必填),指定本地测试节点的 RPC 地址(如 http('http://localhost:8545') )。 |
chain |
Chain |
区块链网络(可选),通常使用 foundry (本地测试链)。 |
account |
`Account | Address` |
pollingInterval |
number |
轮询频率(毫秒,默认 4000),用于监听链上状态更新。 |