您现在的位置是:首页 >其他 >使用Hardhat测试智能合约网站首页其他
使用Hardhat测试智能合约
Hardhat是一个编译、部署、测试和调试以太坊应用的开发环境。它可以帮助开发人员管理和自动化构建智能合约和dApps过程中固有的重复性任务,并围绕这一工作流程轻松引入更多功能。这意味着hardhat在最核心的地方是编译、运行和测试智能合约。
Hardhat内置了Hardhat网络,这是一个专为开发设计的本地以太坊网络。主要功能有Solidity调试,跟踪调用堆栈、console.log()和交易失败时的明确错误信息提示等。
在Hardhat中编写智能合约测试是使用JavaScript或TypeScript完成的。
使用Waffle的测试是用Mocha和Chai一起编写的。
Mocha是流行的JavaScript测试框架之一,通过它添加和运行测试,从而保证代码质量。
```
const { expect } = require("chai");
describe("Greeter", function() {
it("Should return the new greeting once it's changed", async function() {
const Greeter = await ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, world!");
await greeter.deployed();
expect(await greeter.greet()).to.equal("Hello, world!");
await greeter.setGreeting("Hola, mundo!");
expect(await greeter.greet()).to.equal("Hola, mundo!");
});
});
```
在终端上运行npx hardhat test, 你应该看到以下输出:
```
$ npx hardhat test
Contract: Greeter
✓ Should return the new greeting once it's changed (762ms)
1 passing (762ms)
```
这意味着测试通过了。 现在我们来解释一下每一行代码:
```
const { expect } = require("chai");
```
我们需要的是 Chai,它是一个断言库。 这些断言函数被称为 匹配器,我们在这里使用的这些函数其实来自Waffle。
这就是为什么我们要使用hardhat-waffle插件的原因,这使得我们更容易从以太坊中断言值。
```
describe("Greeter", function () {
it("Should return the new greeting once it's changed", async function () {
// ...
});
});
```
这个包装器只是遵循Mocha提出的测试结构,但你可能已经注意到在it的回调函数中使用了async。 与以太坊网络和智能合约的交互是异步操作,因此大多数API和库都使用JavaScript的Promise来返回值。 使用 async可以让我们通过 await等待对合约和Hardhat网络节点的调用。
```
const Greeter = await ethers.getContractFactory("Greeter");
```
ethers.js中的ContractFactory是一个用于部署新的智能合约的抽象,所以这里的Greeter是我们的greeter合约实例的工厂。
```
const greeter = await Greeter.deploy("Hello, world!");
```
在 ContractFactory上调用 deploy()将开始部署,并返回一个解析为 Contract的 Promise。 这是一个合约对象,在这个对象上可以条用每个智能合约函数。 这里我们要把字符串 Hello, world!传递给合约的构造函数。
一旦合约部署完毕,就可以在greeter上调用合约方法,用它们来获取合约的状态。
```
expect(await greeter.greet()).to.equal("Hello, world!");
```
在这里,我们使用Contract实例来调用Solidity代码中的智能合约函数。 greet()返回迎接者的问候语,我们正在检查它是否等于Hello, world!,因为它应该相等。 这里,我们使用了Chai匹配器expect、to和equal。
```
await greeter.setGreeting("Hola, mundo!");
expect(await greeter.greet()).to.equal("Hola, mundo!");
```
我们可以用相同的方式修改合约的状态, 调用 setGreeting将设置一个新的问候信息。 在解析了 Promise之后,我们再进行一次断言,以验证问候语是否真正改变了。