⛑️

hardhatにJest入れたらエラーが出たので、対処した話

2023/03/14に公開

どうも、アカネです(・ω・)ノ
solidityを勉強し出したら普通のNFTじゃ満足できなくなってきたクリエイターです。

いろいろ調べていたらdescribeやitのeachってやつを使いたくなったのですが、そのままだと使えなかったので、Jestをインストールして既存のテストを書き換えてみたぜ! っていう話をしたいと思います。

Jestの始め方はこちら
https://jestjs.io/ja/docs/getting-started

Jestの使い方(かんたんに)

手順はすぐ上のリンク先のJest公式資料に書いてあるんですけど、いくつか注意点があります。

  1. npm install --save-dev jest
  2. package.jsonに以下を追加(※)
{
  "scripts": {
    "test": "npx hardhat compile; jest"
  }
}
  1. 名前が〇〇.test.jsのファイルを作成し、テストを書く。または既存のファイルをリネームする。
  1. リネームして作った場合、これが書いてあったら消しておく(Jestのexpectを使いたいので)
const { expect } = require("chai");
  1. npm test

これだけでテストが走るはずです。

追記: (※)手順2の変更について

気付いてしまいましたか? 手順2に書いた内容が公式資料と異なることに。。。

コンパイルしていない状態で npm test を実行すると getContractFactoryで HardhatError: HH700: Artifact for contract 〇〇 not found. ってエラーが出てしまうことがわかりました。

発生源は、こういう箇所ですね↓

const t = await ethers.getContractFactory("〇〇");
const token = await t.deploy();
await token.deployed();

公式資料で scripts>test の中身に入れられてるのはjestだけなのですが、それだと初回やnpx hardhat cleanでキャッシュ消した後に別途コンパイル叩かねば上記のエラーが出てしまい、非常に煩わしいです。
なのでテストする時に必ずコンパイルを行うよう、手順2にあるようにnpx hardhat compile;と書き加えることをオススメします。

エラーに対処する

私の環境(既存のファイルをリネームしただけでテスト実行した)で発生したエラーを振り返ります。

ReferenceError: ethers is not defined

ethersなんて知らんよ!って言われたので1行追加したら解決しました。

const { ethers } = require("hardhat");

TypeError: Cannot read properties of undefined (reading 'equal')

equalなんて知らんよ!って言われてます。
問題が出たコードはこんなかんじ↓

token.mint(owner.address, 0, 100);
expect(await token.balanceOf(owner.address, 0)).to.equal(100);

.to.equal.toEqualに置換したら解決しました。

token.mint(owner.address, 0, 100);
expect(await token.balanceOf(owner.address, 0)).toEqual(100);

さっきまで一致してたのに。。。

「ちゃんと意図通りの枚数ミントされてるかなー?」ってテストしてる箇所が、Jest導入前まで問題なかったのにexpectで引っかかるようになっちゃいました(´・ω・`)

   expect(received).toEqual(expected) // deep equality

    Expected: 100
    Received: {"hex": "0x64", "type": "BigNumber"}

      29 |
      30 |     token.mint(owner.address, 0, 100);
    > 31 |     expect(await token.balanceOf(owner.address, 0)).toEqual(100);

どうもbalanceOfがBigNumber返してるから、データ型不一致のためちゃんと数値比較してくれなくなっちゃったもよう。

toNumber()を噛ませたら解決しました。

token.mint(owner.address, 0, 100);
let balance = await token.balanceOf(owner.address, 0);
expect(balance.toNumber()).toEqual(100);

今回私が遭遇したエラーは、以上です!


こちらのサンプルコードが参考になりました。
https://github.com/comingAlive/hardhat-jest-example/blob/master/test/lottery.test.ts

同じこと試す方、うまくいきますように!(・ω・)ノシ

Discussion