Hardhat测试报错:Cannot read properties of undefined (reading 'getContract')
ethers.getContract未定义错误 问题描述
执行yarn hardhat test测试FundMe合约时触发以下错误:
TypeError: Cannot read properties of undefined (reading 'getContract')
错误定位至test\unit\FundMe.test.js第20行。同时VS Code提示Property 'getContract' may not exist on type 'typeof import',确认导入的ethers对象中不存在该方法。
核心测试代码片段:
const {deployments, ethers, getNamedAccounts } = require("hardhat") const {assert } = require("chai") describe("FundMe", async function () { let fundMe let deployer let mockV3Aggregator beforeEach(async function() { const {deployer} = await getNamedAccounts() await deployments.fixture(['all']) fundMe = await ethers.getContract("FundMe", deployer) // 错误触发行 mockV3Aggregator = await ethers.getContract("MockV3Aggregator", deployer) }) // ... 测试用例 })
当前开发依赖:
"devDependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/providers": "^5.7.2", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-network-helpers": "^1.0.8", "@nomicfoundation/hardhat-toolbox": "^2.0.1", "@nomiclabs/hardhat-ethers": "^2.2.2", "@nomiclabs/hardhat-etherscan": "^3.1.6", "@typechain/ethers-v5": "^10.2.0", "@typechain/hardhat": "^6.1.5", "chai": "^4.3.7", "ethers": "5.7.2", "hardhat": "^2.12.7", "hardhat-deploy": "^0.11.23", }
问题根源
ethers.getContract并非原生Ethers.js的内置方法,而是hardhat-deploy插件为Hardhat的ethers对象扩展的专属功能。错误的主要诱因:
- Hardhat配置文件未正确引入
hardhat-deploy插件,导致扩展方法未生效; - 依赖版本冲突,
hardhat-deploy与hardhat-ethers的兼容性问题导致扩展方法无法被识别。
解决方案
1. 确认Hardhat配置中引入hardhat-deploy
打开hardhat.config.js,确保顶部已添加插件引入:
require("hardhat-deploy"); require("@nomicfoundation/hardhat-toolbox"); // 其他配置项...
若使用TypeScript,需改为:
import "hardhat-deploy"; import "@nomicfoundation/hardhat-toolbox"; // 其他配置项...
2. 改用hardhat-deploy标准方式获取合约
若插件已配置但仍报错,可直接通过deployments对象获取合约部署信息,再连接到指定签名者:
beforeEach(async function() { // 修复局部变量覆盖问题,给外部deployer变量赋值 deployer = (await getNamedAccounts()).deployer; await deployments.fixture(['all']); // 通过deployments.get获取合约元数据,再用getContractAt连接签名者 const fundMeDeployment = await deployments.get("FundMe"); fundMe = await ethers.getContractAt(fundMeDeployment.abi, fundMeDeployment.address, deployer); const mockDeployment = await deployments.get("MockV3Aggregator"); mockV3Aggregator = await ethers.getContractAt(mockDeployment.abi, mockDeployment.address, deployer); })
3. 解决依赖冲突
@nomicfoundation/hardhat-toolbox已内置@nomiclabs/hardhat-ethers,而hardhat-deploy自带适配的ethers集成,重复依赖会导致冲突。执行以下命令清理冲突:
yarn remove @nomiclabs/hardhat-ethers yarn install
额外注意事项
测试代码中beforeEach内的const {deployer}是局部变量,会覆盖外部声明的deployer变量,导致其始终为undefined,需改为deployer = (await getNamedAccounts()).deployer完成赋值。
内容的提问来源于stack exchange,提问作者Paul Bradley

