Events
使用 hardhat + chai 測試合約事件的參數
我目前正在使用
chai
並hardhat
測試ethereum-waffle
我的智能合約:const chai = require('chai') const hre = require('hardhat') const { solidity } = require('ethereum-waffle') chai.use(solidity)
我一直覺得它很好用。
但是,我在測試事件時遇到了一些困難。我目前使用
expect( ... ).to.emit( ... ).withArgs( ... )
的適用於很多情況,但不是全部。從測試中獲取以下範例片段:
const destroyResult = await gameContract.attack([4, 0]) // Expect the game to end with the announced winner being owner expect(destroyResult) .to.emit(gameContract, 'GameEnd') .withArgs(undefined, owner.address)
在這個例子中,GameEnd 事件有兩個參數:遊戲結束的時間戳和獲勝者的地址(
owner.address
上圖)。在我的測試中,我只關心測試第二個參數(誰贏得了比賽)。我嘗試提供
undefined
時間戳,但這是不可接受的,並導致測試失敗。我需要的是一種只測試事件的第二個參數的方法。對於我來說,擁有一個可以訪問事件對象的函式也是可以接受的,這樣我就可以執行我喜歡的任何測試。但是我還沒有看到這樣做的任何方法。
任何幫助將不勝感激,謝謝!
這就是我為 ERC20 代幣的 Transfer 事件執行此操作的方式:
通常 :
await expect(tokenInstance.connect(<signer-account>).transfer(<addr-of-receipent>, <amount-BigNumber>)) .to.emit(tokenInstance, 'Transfer').withArgs(<addr-of-signer-account>, <addr-of-receipent>, <amount-BigNumber>);
這就是您如何獲取所有參數並測試所有參數或其中任何一個的方法:
... const tx = await tokenInstance.connect(<signer-account>).transfer(<addr-of-receipent>, <amount-BigNumber>); const receipt = await ethers.provider.getTransactionReceipt(tx.hash); const interface = new ethers.utils.Interface(["event Transfer(address indexed from, address indexed to, uint256 amount)"]); const data = receipt.logs[0].data; const topics = receipt.logs[0].topics; const event = interface.decodeEventLog("Transfer", data, topics); expect(event.from).to.equal(<addr-of-signer-account>); expect(event.to).to.equal(<addr-of-receipent>); expect(event.amount.toString()).to.equal(<amount-BigNumber>.toString()); ...
我在這裡假設只會發出一個事件,因此我得到了日誌數組中的第一個元素
logs[0]