Jest测试Ethers.js智能合约getData函数时如何Mock网络相关对象
解决Ethers.js测试中的Mock问题
问题原因
你的测试Mock不完整:ethers.providers.Web3Provider的实例没有正确模拟,导致创建合约时触发网络检测失败;同时ethers.Contract也没有关联到你定义的mock合约对象,才会抛出"could not detect network"错误。
完整Mock方案
1. 全局Mock Ethers模块
直接用jest替换整个ethers库,确保测试时调用的是Mock版本而非真实库:
jest.mock('ethers', () => { // 定义预设返回值的mock合约实例 const mockContract = { cost: jest.fn().mockResolvedValue(5), totalSupply: jest.fn().mockResolvedValue(50) }; return { providers: { // Mock Web3Provider,返回带有网络信息的实例,避免网络检测报错 Web3Provider: jest.fn().mockImplementation(() => ({ getNetwork: jest.fn().mockResolvedValue({ chainId: 1 }), _network: { chainId: 1 } // 适配部分ethers版本直接访问此属性的逻辑 })) }, // 让Contract构造函数直接返回我们的mock合约实例 Contract: jest.fn().mockReturnValue(mockContract) }; });
2. 初始化window.ethereum
只需要让它存在即可,无需复杂Mock:
window.ethereum = {};
3. 完整测试代码
it('getData function should set cost and totalSupply to data', async () => { // 确保window.ethereum存在 window.ethereum = {}; // 执行目标方法 await wrapper.vm.getData(); // 断言结果符合预期 expect(wrapper.vm.data.cost).toBe('5'); expect(wrapper.vm.data.totalSupply).toBe('50'); // 可选:验证Mock对象的调用逻辑是否正确 const ethers = require('ethers'); expect(ethers.providers.Web3Provider).toHaveBeenCalledWith(window.ethereum); expect(ethers.Contract).toHaveBeenCalled(); });
关键说明
- Mock Web3Provider核心:必须提供
getNetwork方法或_network属性,因为ethers创建合约时会自动检测网络状态,缺少这些会触发网络检测失败错误。 - 关联Contract与Mock实例:让
ethers.Contract的Mock直接返回预设的合约实例,这样调用contract.cost()时会使用你提前设置的返回值。 - 简化window.ethereum:只要它存在就能通过
typeof window.ethereum !== 'undefined'的判断,不需要额外Mock方法。
内容的提问来源于stack exchange,提问作者DamTan
相关产品推荐
相关产品推荐

