本周,当我们的朋友帕特里克·柯林斯在Chainlink Spring 2022黑客马拉松的日程安排中交谈时,我了解到在测试中提前进入区块链的可能性:
async moveTime(amount: number) {
console.log("Moving blocks...");
await network.provider.send("evm_increaseTime", [amount]);
console.log(`Moved forward in time ${amount} seconds`);
}所以我试着在我的测试中使用它,但是,从我开始使用它的那一刻起,我的测试就开始有这个异常:
Error: nonce has already been used [ See: https://links.ethers.org/v5-errors-NONCE_EXPIRED ] (error={"name":"InvalidInputError","code":-32000,"_isProviderError":true}, method="sendTransaction", transaction="0x02f872827a69148459682f008461277a0a8401bad45894532323de74bab864b7005d910e5bd8562d038b9b8084478c7d5fc001a0e987896b237af1c098617321e8356a5dd903b834f7fe9e4188f6b5858530d263a06fce96280dc21b5d41909353ae33897f4155a3742d1deefac0f77575d9ec9151", code=NONCE_EXPIRED, version=providers/5.6.1)我在纳塞_本地硬顶帽节点上的ethers.js过期错误上发现了类似的类似错误,并遵循了有关执行快照的说明,但它并没有解决这个问题:
before(async function () {
const accounts = waffle.provider.getWallets();
....
this.loadFixture = waffle.createFixtureLoader(accounts);
snapshot = await waffle.provider.send("evm_snapshot", []);
});
after(async function () {
await waffle.provider.send("evm_revert", [snapshot]);
});其他人面对这样的问题并成功地解决了它吗?
注意:错误并不发生在所有的执行中,仅当我在上一次执行几秒钟后运行测试时。
致以敬意,
发布于 2022-05-13 15:41:33
我发现了我上面报告的问题的原因。特别是在我的例子中,问题与JSON方法evm_increaseTime无关,解决方案也不是快照块链。
问题是,在我的一些测试中,当断言事件发出并恢复条件时,我以错误的方式进行了。
与常规断言相反,我们将被断言的值传递给expect函数:
expect(BigNumber.from(100)).to.be.within(BigNumber.from(99), BigNumber.from(101));当然,如果是远程调用,我们使用await来不传递承诺,但返回的实际值:
expect(await token.balanceOf(wallet.address)).to.equal(993);要断言发出的事件和恢复,我们可以**将承诺传递给expect,并且我们必须使用expect函数的等待:
await expect(token.transfer(walletTo.address, 7))
.to.emit(token, 'Transfer')
.withArgs(wallet.address, walletTo.address, 7);
await expect(token.transfer(walletTo.address, 1007))
.to.be.revertedWith('Insufficient funds');在Waffle文档中甚至有这样的注释:
您必须等待expect,才能使matcher正确执行。如果不等待,将导致断言传递,而不管事件是否实际发出!
在检查了我所有的测试代码并修复了所有出现的错误后,它运行得很好。
**当我将合同的函数调用所返回的承诺传递给expect函数时,以及在函数调用之前利用等待并不顾承诺传递收据本身时,我的测试工作得很好。
https://ethereum.stackexchange.com/questions/127120
复制相似问题