How to directly test a Solidity Library with Hardhat/Chai

Viewed 168

I'm trying to test a Solidity Library directly using hardhat and chaï. This is a Library example I would like to test:

library LibTest {
    function testFunc() public view returns(bool) {
        return true;
    }
}

and this is how I'm trying to test it.

beforeEach(async () => {
    const LibTest = await ethers.getContractFactory("LibTest");
    const libTest = await LibTest.deploy();
    await libTest.deployed();
})

describe('Testing test()', function () {
    it("is working testFunc ?", async function () {
      console.log(await libTest.testFunc());
    })
})

But I have the error message:

ReferenceError: libTest is not defined

I read everything I can on Chai doc and Hardhat doc but can't found any solution

2 Answers

I would say to use fixture and also utilize waffle and to deploy the library contract once and save the snapshot of the contract:

const {loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const {expect} = require('chai');

const {ethers, waffle} = require('hardhat');

const {deployContract} = waffle;
const LibArtifact = require('../artifacts/contracts/lib.sol/LibTest.json');

describe("Lib tests", function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshopt in every test.
  async function deployOnceFixture() {

    const [owner, ...otherAccounts] = await ethers.getSigners();
    lib = (await deployContract(owner, LibArtifact));

    return { lib, owner, otherAccounts };
  }

  describe("Testing test()", function () {
    it("s working testFunc ?", async function () {
      const { lib } = await loadFixture(deployOnceFixture); 
      expect(await lib.testFunc()).to.be.true;
    });
  });
});

Instructions to add the waffle plugin: Hardhat-waffle Basically, you need to install the libraries:

npm install --save-dev @nomiclabs/hardhat-waffle 'ethereum-waffle@^3.0.0' @nomiclabs/hardhat-ethers 'ethers@^5.0.0'

And then import hardhat-waffle in the hardhat-config.js file:

require("@nomiclabs/hardhat-waffle");

Also, notice I put the test file in a test directory so I needed to go back one folder to find artifacts generated by running npx hardhat compile. For convenience I pushed the solution in a Github repo: https://github.com/Tahlil/run-solidity-lib

The best way I have found to go about this is to create a LibTest.sol contract that invokes and tests the Lib itself. And just running abstracted tests in JS/TS to invoke the LibTest contract, connecting the Lib.sol contract to it during deployment in Hardhat.

const Lib = await ethers.getContractFactory("Lib");
const lib = await Lib.deploy();
const LibTest = await ethers.getContractFactory("LibTest", {
    libraries: {
      Lib: lib.address,
    },
  });
const libTest = await LibTest.deploy();
/// later: console.log(await libTest.testLibFunc());

LibTest.sol:

import "./Lib.sol";
library LibTest {
    function testLibFunc() public view returns(bool) {
        bool response = Lib.testFunc();
        return response;
    }
}

Were you able to find a better method?

Related