Level 7 FundMe.test.js searched all duscussion still get same error TypeError: ethers.getContract is not a function ... Please Help update code of FundMe.test.js
UmitRock opened this issue · 1 comments
UmitRock commented
i search all issues and discussion never found my solution even i did copied patrick contract level 7 same issues and even downgrade ether to v5 not work...
but contract Deployed Fundme on test net and node hardhat network too >>>>>>>>only have issues on testing fundme
constructor
1) "before each" hook for "sets the aggregator addresses correctly"
0 passing (2s)
1 failing
1) FundMe
"before each" hook for "sets the aggregator addresses correctly":
TypeError: ethers.getContract is not a function
at Context.<anonymous> (test/unit/FundMe.test.js:17:31)
thats FundMe.test.js code
const { assert, expect } = require("chai");
const { network, deployments, ethers } = require("hardhat");
const { developmentChains } = require("../../helper-hardhat-config");
!developmentChains.includes(network.name)
? describe.skip
: describe("FundMe", function () {
let fundMe;
let mockV3Aggregator;
let deployer;
const sendValue = ethers.utils.parseEther("1");
beforeEach(async () => {
// const accounts = await ethers.getSigners()
// deployer = accounts[0]
deployer = (await getNamedAccounts()).deployer;
await deployments.fixture(["all"]);
fundMe = await ethers.getContract("FundMe", deployer);
mockV3Aggregator = await ethers.getContract(
"MockV3Aggregator",
deployer
);
});
describe("constructor", function () {
it("sets the aggregator addresses correctly", async () => {
const response = await fundMe.getPriceFeed();
assert.equal(response, mockV3Aggregator.address);
});
});
describe("fund", function () {
// https://ethereum-waffle.readthedocs.io/en/latest/matchers.html
// could also do assert.fail
it("Fails if you don't send enough ETH", async () => {
await expect(fundMe.fund()).to.be.revertedWith(
"You need to spend more ETH!"
);
});
// we could be even more precise here by making sure exactly $50 works
// but this is good enough for now
it("Updates the amount funded data structure", async () => {
await fundMe.fund({ value: sendValue });
const response = await fundMe.getAddressToAmountFunded(deployer);
assert.equal(response.toString(), sendValue.toString());
});
it("Adds funder to array of funders", async () => {
await fundMe.fund({ value: sendValue });
const response = await fundMe.getFunder(0);
assert.equal(response, deployer);
});
});
describe("withdraw", function () {
beforeEach(async () => {
await fundMe.fund({ value: sendValue });
});
it("withdraws ETH from a single funder", async () => {
// Arrange
const startingFundMeBalance = await fundMe.provider.getBalance(
fundMe.address
);
const startingDeployerBalance = await fundMe.provider.getBalance(
deployer
);
// Act
const transactionResponse = await fundMe.withdraw();
const transactionReceipt = await transactionResponse.wait();
const { gasUsed, effectiveGasPrice } = transactionReceipt;
const gasCost = gasUsed.mul(effectiveGasPrice);
const endingFundMeBalance = await fundMe.provider.getBalance(
fundMe.address
);
const endingDeployerBalance = await fundMe.provider.getBalance(
deployer
);
// Assert
// Maybe clean up to understand the testing
assert.equal(endingFundMeBalance, 0);
assert.equal(
startingFundMeBalance.add(startingDeployerBalance).toString(),
endingDeployerBalance.add(gasCost).toString()
);
});
// this test is overloaded. Ideally we'd split it into multiple tests
// but for simplicity we left it as one
it("is allows us to withdraw with multiple funders", async () => {
// Arrange
const accounts = await ethers.getSigners();
for (i = 1; i < 6; i++) {
const fundMeConnectedContract = await fundMe.connect(accounts[i]);
await fundMeConnectedContract.fund({ value: sendValue });
}
const startingFundMeBalance = await fundMe.provider.getBalance(
fundMe.address
);
const startingDeployerBalance = await fundMe.provider.getBalance(
deployer
);
// Act
const transactionResponse = await fundMe.cheaperWithdraw();
// Let's comapre gas costs :)
// const transactionResponse = await fundMe.withdraw()
const transactionReceipt = await transactionResponse.wait();
const { gasUsed, effectiveGasPrice } = transactionReceipt;
const withdrawGasCost = gasUsed.mul(effectiveGasPrice);
console.log(`GasCost: ${withdrawGasCost}`);
console.log(`GasUsed: ${gasUsed}`);
console.log(`GasPrice: ${effectiveGasPrice}`);
const endingFundMeBalance = await fundMe.provider.getBalance(
fundMe.address
);
const endingDeployerBalance = await fundMe.provider.getBalance(
deployer
);
// Assert
assert.equal(
startingFundMeBalance.add(startingDeployerBalance).toString(),
endingDeployerBalance.add(withdrawGasCost).toString()
);
// Make a getter for storage variables
await expect(fundMe.getFunder(0)).to.be.reverted;
for (i = 1; i < 6; i++) {
assert.equal(
await fundMe.getAddressToAmountFunded(accounts[i].address),
0
);
}
});
it("Only allows the owner to withdraw", async function () {
const accounts = await ethers.getSigners();
const fundMeConnectedContract = await fundMe.connect(accounts[1]);
await expect(fundMeConnectedContract.withdraw()).to.be.revertedWith(
"FundMe__NotOwner"
);
});
});
});
and contract FundMe.sol code is :
// SPDX-License-Identifier: MIT
// 1. Pragma
pragma solidity ^0.8.7;
// 2. Imports
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "./PriceConverter.sol";
// 3. Interfaces, Libraries, Contracts
error FundMe__NotOwner();
/**@title A sample Funding Contract
* @author Patrick Collins
* @notice This contract is for creating a sample funding contract
* @dev This implements price feeds as our library
*/
contract FundMe {
// Type Declarations
using PriceConverter for uint256;
// State variables
uint256 public constant MINIMUM_USD = 50 * 10 ** 18;
address private immutable i_owner;
address[] private s_funders;
mapping(address => uint256) private s_addressToAmountFunded;
AggregatorV3Interface private s_priceFeed;
// Events (we have none!)
// Modifiers
modifier onlyOwner() {
// require(msg.sender == i_owner);
if (msg.sender != i_owner) revert FundMe__NotOwner();
_;
}
// Functions Order:
//// constructor
//// receive
//// fallback
//// external
//// public
//// internal
//// private
//// view / pure
constructor(address priceFeed) {
s_priceFeed = AggregatorV3Interface(priceFeed);
i_owner = msg.sender;
}
/// @notice Funds our contract based on the ETH/USD price
function fund() public payable {
require(
msg.value.getConversionRate(s_priceFeed) >= MINIMUM_USD,
"You need to spend more ETH!"
);
// require(PriceConverter.getConversionRate(msg.value) >= MINIMUM_USD, "You need to spend more ETH!");
s_addressToAmountFunded[msg.sender] += msg.value;
s_funders.push(msg.sender);
}
function withdraw() public onlyOwner {
for (
uint256 funderIndex = 0;
funderIndex < s_funders.length;
funderIndex++
) {
address funder = s_funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}
s_funders = new address[](0);
// Transfer vs call vs Send
// payable(msg.sender).transfer(address(this).balance);
(bool success, ) = i_owner.call{value: address(this).balance}("");
require(success);
}
function cheaperWithdraw() public onlyOwner {
address[] memory funders = s_funders;
// mappings can't be in memory, sorry!
for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}
s_funders = new address[](0);
// payable(msg.sender).transfer(address(this).balance);
(bool success, ) = i_owner.call{value: address(this).balance}("");
require(success);
}
/** @notice Gets the amount that an address has funded
* @param fundingAddress the address of the funder
* @return the amount funded
*/
function getAddressToAmountFunded(
address fundingAddress
) public view returns (uint256) {
return s_addressToAmountFunded[fundingAddress];
}
function getVersion() public view returns (uint256) {
return s_priceFeed.version();
}
function getFunder(uint256 index) public view returns (address) {
return s_funders[index];
}
function getOwner() public view returns (address) {
return i_owner;
}
function getPriceFeed() public view returns (AggregatorV3Interface) {
return s_priceFeed;
}
}
i hope anyone help me and thanks :)
NIAZELOPER commented
@UmitRock Hey
Use getContractAt instead of getContract:
First use deployments.get() function as
// Get the Signer first for getContractAt():
const accounts = await ethers.getSigners(); // This will give array of signers
const Signer = accounts[0]; // This will give deployer signer
const Contract = await deployments.get("FundMe");
Now implement getContractAt() as:
const fundMe = await ethers.getContractAt( Contract.abi, Contract.address, signer);
Do the same for Mock.
Hope it helps