You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:40:36