강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của dev8657
dev8657

câu hỏi đã được viết

Phát triển BApp EVM Blockchain cho mọi người - Giới thiệu

npx hardhat test ./test/Greeter.test 실행시 에러가 납니다.

Đã giải quyết

Viết

·

255

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가 있어서 그런건지 해결방법을 잘 모르겠습니다.

도와주세요 ㅠ

 

블록체인Smart Contractnft

Câu trả lời 1

0

captainmomo님의 프로필 이미지
captainmomo
Người chia sẻ kiến thức

최신 라이브러리 버젼과 코드 호환이 안 되는걸 확인했습니다.

강의 제작당시 버전으로 fix해 두었으니

  • node_modules 폴더와 package-lock.json 파일을 삭제

  • 강의 코드 최신버전으로 git pull

  • npx hardhat test ./test/Greeter.test 실행

이 방법으로 실행되는걸 확인했습니다.

dev8657님의 프로필 이미지
dev8657
Người đặt câu hỏi

감사합니다! 정상적으로 실행되는 것을 확인했습니다.

Hình ảnh hồ sơ của dev8657
dev8657

câu hỏi đã được viết

Đặt câu hỏi