如何在测试中Mock ethers.js Provider以实现MetaMask检测?
解决方案:Mock Ethers Provider 注入虚假地址
不需要依赖第三方mock库,直接手动模拟ethers的结构就能满足需求,以下是基于Jest的实现示例(其他测试框架思路一致):
步骤1:手动Mock Ethers库
在测试文件中直接mock ethers 的 Web3Provider,让它返回预设的签名器对象,签名器的 getAddress 方法返回你需要的虚假地址:
jest.mock('ethers', () => ({ providers: { Web3Provider: jest.fn().mockImplementation(() => ({ getSigner: jest.fn().mockReturnValue({ getAddress: jest.fn().mockResolvedValue('0x1234567890abcdef1234567890abcdef12345678') }) }) } }));
步骤2:模拟全局的window.ethereum
原代码依赖浏览器环境的 window.ethereum 对象,测试环境中需要手动挂载:
global.window.ethereum = {};
步骤3:编写测试断言
导入你的业务代码并执行测试,验证地址是否符合预期,同时可验证相关方法的调用情况:
import { yourMetaMaskDetectionLogic } from './your-business-file'; test('获取Mock的MetaMask地址', async () => { const address = await yourMetaMaskDetectionLogic(); // 断言地址匹配预设值 expect(address).toBe('0x1234567890abcdef1234567890abcdef12345678'); // 验证Web3Provider是否按预期初始化 expect(ethers.providers.Web3Provider).toHaveBeenCalledWith(window.ethereum, 'any'); // 验证getSigner方法是否被调用 expect(ethers.providers.Web3Provider().getSigner).toHaveBeenCalled(); });
核心思路
手动mock完全可控,能精准模拟你需要的每一层调用,避免第三方mock库的适配问题。如果使用Vitest等其他测试框架,只需要把Jest的API替换成对应框架的mock方法即可(比如 vi.mock 替代 jest.mock)。
内容的提问来源于stack exchange,提问作者matty
相关产品推荐
相关产品推荐

