In a hardhat project I'm using smock to mock an ERC20 contract and chai's calledOnce to assert:

    const {expect} = require("chai")
    const {artifacts, ethers} = require("hardhat")
    const {smock} = require("@defi-wonderland/smock")

    it("Should successfuly invoke transfer of given ERC20", async () => {
        const MyContractFactory = await ethers.getContractFactory("MyContract")
        const myContract = await MyContractFactory.deploy()
        await myContract.deployed()

        const fakeERC20 = await smock.fake('IERC20');

        const erc20Contract = fakeERC20.address
        const amount = 5
        const to = '0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8'

        const txReceipt = await myContract.myTransfer(erc20Contract, to, amount)

        expect(fakeERC20.transfer).to.have.been.calledWith(to, amount);

I'm getting an error:

Error: Invalid Chai property: calledOnce

I've tried using sinon and explained here but got another error:

TypeError: { [Function]
   { callHistory: [ [Object] ],
     name: 'transfer',
     answerByIndex: {},
     answerByArgs: [],
     encoder: [Function],
     defaultAnswer: { value: true, shouldRevert: false } },
  atCall: [Function: bound atCall],
  getCall: [Function: bound getCall],
  returns: [Function: bound returns],
  returnsAtCall: [Function: bound returnsAtCall],
  reverts: [Function: bound reverts],
  revertsAtCall: [Function: bound revertsAtCall],
  whenCalledWith: [Function: bound whenCalledWith],
  reset: [Function: bound reset] } is not a spy or a call to a spy!

Any ideas?

2 Answers 2


Solved by adding


So basically you should:

  • Follow the official documentation of smock (an awesome library!)

  • If your tests are failing with Invalid Chai property when calling calledOnce you should install sinon and sinon-chai.

  • Eventually your imports look more or less like:

    const chai = require('chai')

    const sinon = require('sinon')

    const sinonChai = require('sinon-chai')

    const {ethers} = require('hardhat')

    const {smock} = require('@defi-wonderland/smock')

    const expect = chai.expect



From here here.

You can resolve this issue by adding the below at the beginning of you test. chai.config.proxyExcludedKeys.push('calledOnce');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.