해결된 질문
작성
·
147
1
npx hardhat test ./test/Greeter.test 실행시 에러가 납니다.
import { expect } from 'chai';
import { ethers, waffle } from 'hardhat';
import GreeterArtifact from '../artifacts/contracts/Greeter.sol/Greeter.json';
import { Greeter } from '../typechain';
// import { BigNumber } from 'ethers';
// import '@nomiclabs/hardhat-waffle';
//* Greeter.sol과 비교하면서 보자!!
describe('Greeter', () => {
let greeter: Greeter;
const initMsg = 'hello blockchain!!!';
//* hardHat에서 만들어진 10개 계정부터 앞에 5개 가져옴.
const [admin, other0, other1, other2, receiver] =
waffle.provider.getWallets();
before(async () => {});
beforeEach(async () => {
//admin계정이 Greeter 배포
greeter = (await waffle.deployContract(admin, GreeterArtifact, [
initMsg,
])) as Greeter; //* Greeter로 형변환 해서 넣어주라는 뜻
});
it('constructor', async () => {
const greetMsg = await greeter.getGreet();
expect(greetMsg).to.be.equal(initMsg);
});
it('setGreeting', async () => {
const secondMsg = 'second greeting msg';
await greeter.setGreeting(secondMsg);
//* 이렇게 unit 테스트인 경우에만 hardhat이 transaction.wait()을 사용하지 않아도 결과를 기다림.
const recvMsg = await greeter.getGreet();
expect(recvMsg).to.be.equal(secondMsg);
});
it('setGreeting with event', async () => {
const secondMsg = 'second greeting msg';
/*
* setGreeting -> non-view함수 -> 채굴할 때까지 기다려야함.
* transaction.wait()을 호출하여 채굴이 끝날 때까지 기다린다.
*/
const transaction = await greeter.setGreeting(secondMsg);
//* transaction을통해 채굴이 끝난 후 영수증을 가져옴.
const receipt = await transaction.wait();
//영수증 안의 이벤트에서 SetGreeting이라는 event만 가져온다.
const event = receipt.events?.filter(x => {
return x.event == 'SetGreeting';
})[0];
//* contract배포자가 admin이라서 자동으로 admin으로 설정됨.
//* ? : undefined가 될수도 있다. ~> 실제로는 예외처리 필요
expect(event?.args?.sender).to.be.equal(admin.address);
expect(event?.args?.oldGreeting).to.be.equal(initMsg);
expect(event?.args?.newGreeting).to.be.equal(secondMsg);
const thirdMsg = 'third greeting msg';
await expect(greeter.setGreeting(thirdMsg))
.to.emit(greeter, 'SetGreeting')
.withArgs(admin.address, secondMsg, thirdMsg);
});
it('getGreetingHistory', async () => {
const secondMsg = 'second greeting msg';
const transaction = await greeter.setGreeting(secondMsg);
const receipt = await transaction.wait();
const thirdMsg = 'third greeting msg';
await expect(greeter.setGreeting(thirdMsg))
.to.emit(greeter, 'SetGreeting')
.withArgs(admin.address, secondMsg, thirdMsg);
const count = await greeter.getGreetingHistoryCount();
expect(count).to.be.equal(3);
const historyAll = await greeter.getGreetingHistoryAll();
expect(historyAll.length).to.be.equal(3);
expect(historyAll[0]).to.be.equal('');
expect(historyAll[1]).to.be.equal(initMsg);
expect(historyAll[2]).to.be.equal(secondMsg);
const secondHistory = await greeter.getGreetingHistoryOne(1);
expect(secondHistory).to.be.equal(initMsg);
//* 없는 인덱스 예상 했을 때 revert메시지 나오는지
await expect(greeter.getGreetingHistoryOne(3)).to.reverted;
});
it('setGreetingPayable', async () => {
const secondMsg = 'second greeting msg';
await expect(greeter.setGreetingPayable(secondMsg)).to.reverted;
//* revert문 예상
await expect(greeter.setGreetingPayable(secondMsg)).to.revertedWith(
'msg.value is not 0.1 ether',
);
await expect(
greeter.setGreetingPayable(secondMsg, {
value: ethers.utils.parseUnits('0.09', 'ether'),
}),
).to.revertedWith('msg.value is not 0.1 ether');
await expect(
greeter.setGreetingPayable(secondMsg, {
value: ethers.utils.parseUnits('0.11', 'ether'),
}),
).to.revertedWith('msg.value is not 0.1 ether');
await greeter.setGreetingPayable(secondMsg, {
//* value를 wei로 바꿔줌.(ehter단위)
value: ethers.utils.parseUnits('0.1', 'ether'),
//~> 이렇게도 가능
// value: BigNumber.from(10).pow(17),
});
const recvMsg = await greeter.getGreet();
expect(recvMsg).to.be.equal(secondMsg);
});
it('withdraw', async () => {
const secondMsg = 'second greeting msg';
//* setGreetingPayable을 실행하기 전에 Ether가 얼마나 들었는지 확인하기 위함.
const oldContractEther = await waffle.provider.getBalance(greeter.address);
expect(oldContractEther).to.be.equal(ethers.utils.parseUnits('0', 'ether'));
//*admin 호출
// await greeter.connect(admin).setGreetingPayable(secondMsg, {
// await greeter.setGreetingPayable(){}
//*admin이 아닌 다른 계정이 호출
await greeter.connect(other0).setGreetingPayable(secondMsg, {
value: ethers.utils.parseUnits('0.1', 'ether'),
});
await greeter.connect(other0).setGreetingPayable(secondMsg, {
value: ethers.utils.parseUnits('0.1', 'ether'),
});
await greeter.connect(other1).setGreetingPayable(secondMsg, {
value: ethers.utils.parseUnits('0.1', 'ether'),
});
await greeter.connect(other2).setGreetingPayable(secondMsg, {
value: ethers.utils.parseUnits('0.1', 'ether'),
});
//위에서 0.1씩 4번 호출 -> 0.4 ether
const newContractEther = await waffle.provider.getBalance(greeter.address);
expect(newContractEther).to.be.equal(
ethers.utils.parseUnits('0.4', 'ether'),
);
const other0Balance = await greeter.balances(other0.address);
const other1Balance = await greeter.balances(other1.address);
const other2Balance = await greeter.balances(other2.address);
expect(other0Balance).to.be.equal(ethers.utils.parseUnits('0.2', 'ether'));
expect(other1Balance).to.be.equal(ethers.utils.parseUnits('0.1', 'ether'));
expect(other2Balance).to.be.equal(ethers.utils.parseUnits('0.1', 'ether'));
//* 얼마나 ether를 들고 있었는지 확인
const oldReceiverEther = await waffle.provider.getBalance(receiver.address);
console.log('oldReceiverEther', oldReceiverEther);
await expect(
greeter.connect(other0).withdraw(receiver.address),
).to.revertedWith('only owner');
//*connect 생략 -> admin
await greeter.withdraw(receiver.address);
const newReceiverEther = await waffle.provider.getBalance(receiver.address);
expect(newReceiverEther.sub(oldReceiverEther)).to.be.equal(
ethers.utils.parseUnits('0.4', 'ether'),
);
const lastContractEther = await waffle.provider.getBalance(greeter.address);
expect(lastContractEther).to.be.equal(
ethers.utils.parseUnits('0', 'ether'),
);
});
});
import { HardhatUserConfig } from 'hardhat/types';
import 'hardhat-typechain';
import '@nomiclabs/hardhat-waffle';
// import 'dotenv/config';
const config: HardhatUserConfig = {
solidity: {
compilers: [
{
version: '0.8.17',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
defaultNetwork: 'hardhat',
networks: {
hardhat: {
accounts: {
count: 10,
},
},
},
mocha: {
timeout: 400000,
},
};
export default config;
아래와 같은 문구가 나타납니다.
Creating Typechain artifacts in directory typechain for target ethers-v5
Successfully generated Typechain artifacts!
Greeter
1) "before each" hook for "constructor"
0 passing (99ms)
1 failing
1) Greeter
"before each" hook for "constructor":
Error: Cannot find module 'ethereum-waffle/dist/cjs/src/deployContract'
Require stack:
- /Users/nareun130/study/nft/basic/node_modules/@nomiclabs/hardhat-waffle/dist/src/deploy.js
- /Users/nareun130/study/nft/basic/node_modules/@nomiclabs/hardhat-waffle/dist/src/index.js
- /Users/nareun130/study/nft/basic/hardhat.config.ts
- /Users/nareun130/study/nft/basic/node_modules/hardhat/internal/core/config/config-loading.js
- /Users/nareun130/study/nft/basic/node_modules/hardhat/internal/cli/cli.js
- /Users/nareun130/study/nft/basic/node_modules/hardhat/internal/cli/bootstrap.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as resolveFilename] (nodemodules/@cspotcode/source-map-support/source-map-support.js:811:30)
at Function.Module._load (node:internal/modules/cjs/loader:981:27)
at Module.require (node:internal/modules/cjs/loader:1231:19)
at require (node:internal/modules/helpers:177:18)
at hardhatDeployContract (node_modules/@nomiclabs/hardhat-waffle/src/deploy.ts:26:7)
at Context.<anonymous> (test/Greeter.test.ts:21:29)
deploy.ts의 26라인을 가봤는데 이렇게 나오는데 node_modules의 경로를 찾아가보니 ethereum-waffle/cjs폴더 안에 src폴더가 없이 바로 아래 deployContract가 있어서 그런건지 해결방법을 잘 모르겠습니다.
도와주세요 ㅠ
답변 1
0
최신 라이브러리 버젼과 코드 호환이 안 되는걸 확인했습니다.
강의 제작당시 버전으로 fix해 두었으니
node_modules 폴더와 package-lock.json 파일을 삭제
강의 코드 최신버전으로 git pull
npx hardhat test ./test/Greeter.test 실행
이 방법으로 실행되는걸 확인했습니다.
감사합니다! 정상적으로 실행되는 것을 확인했습니다.