'Implementing fixtures with @nomiclabs/hardhat-waffle

In the official waffle documentation you may find the next way to implement fixtures:

import {expect} from 'chai';
import {loadFixture, deployContract} from 'ethereum-waffle';
import BasicTokenMock from './build/BasicTokenMock';

describe('Fixtures', () => {
  async function fixture([wallet, other], provider) {
    const token = await deployContract(wallet, BasicTokenMock, [
      wallet.address, 1000
    ]);
    return {token, wallet, other};
  }

  it('Assigns initial balance', async () => {
    const {token, wallet} = await loadFixture(fixture);
    expect(await token.balanceOf(wallet.address)).to.equal(1000);
  });

  it('Transfer adds amount to destination account', async () => {
    const {token, other} = await loadFixture(fixture);
    await token.transfer(other.address, 7);
    expect(await token.balanceOf(other.address)).to.equal(7);
  });
});

However, this won't work while using the plugin on hardhat. No official instructions were given on the plugin docs.

Answer below.



Solution 1:[1]

Although you may be able to find a solution on your own by "Alt + Clicking" on every variable until to come up with the right type structure, better use this snippet:

The following works on Typescript, if you want to use it on javascript just switch to using "require()" imports as well as getting rid of the types:

    import {Wallet, Contract} from "ethers";
    import {MockProvider} from "ethereum-waffle";
    import {ethers, waffle} from "hardhat";
    const {loadFixture, deployContract} = waffle;


//Contract ABI
// For typescript only!
// In order to be able to import .json files make sure you tsconfig.json has set "compilerOptions" > "resolveJsonModule": true. My tsconfig.json at the bottom!
//For obvious reasons change this to the path of your compiled ABI

  import * as TodoListABI from "../artifacts/contracts/TodoList.sol/TodoList.json";

    //Fixtures
  async function fixture(_wallets: Wallet[], _mockProvider: MockProvider) {
    const signers = await ethers.getSigners();
    let token: Contract = await deployContract(signers[0], TodoListABI);
    return {token};
  }

And then, within your mocha-chai tests

it("My unit test", async function () {
    const {token} = await loadFixture(fixture);
    // Your code....
  });

My tsconfig.json for this hardhat project

{
  "compilerOptions": {
    "target": "es2018",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "resolveJsonModule": true
  },
  "include": ["./scripts", "./test"],
  "files": ["./hardhat.config.ts"]
}

Solution 2:[2]

Remember, hardhat uses mocha as its test runner, so you can use the hooks that mocha describes in its documentation: before(), after(), beforeEach(), and afterEach().

Here's an example of deploying a token contract and using the contract instance to run tests.

beforeEach(async function () {
  
  Token = await ethers.getContractFactory("Token");
  [owner, addr1, addr2, ...addrs] = await ethers.getSigners();

  hardhatToken = await Token.deploy();
});
  
describe("Deployment", function () {

  it("Should set the right owner", async function () {
    expect(await hardhatToken.owner()).to.equal(owner.address);
  });
  
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Edward Casanova
Solution 2 Jon Reiland