title | actions | requireLogin | material | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
保持游戏趣味性 |
|
true |
|
到目前为止都做得很好!可以确定的是我们的用户会创建新僵尸了👌🏻。
然而,如果他们能够一直调用这个函数,给他们的军队创造无限僵尸,那么游戏就没意思了。因此,在第2课第4章中,我们给 createZombieFunction()
添加了一个 require
语句,以确保每个用户所拥有的僵尸不超过一个:
require(ownerZombieCount[msg.sender] == 0)
让我们来测试下这个特性,看看它是否有效。
🤞短短几分钟后,我们会有不止一个测试,并且每个测试都应该从头开始。因此,对于每个测试,我们都必须创建一个智能合约的新实例,如下所示:
const contractInstance = await CryptoZombies.new();
如果可以只编写一次,然后让 Truffle 在每次测试时自动运行它,岂不是很棒吗?
嗯…… Mocha(和 Truffle)的一个特性是能够在测试之前或之后运行一些称为 hooks 的代码片段。要在执行测试之前运行某个东西,代码应该放在一个名为 beforeEach()
的函数中。
因此,不需要多次编写 contract.new()
,只用这样写一次就行:
beforeEach(async () => {
// let's put here the code that creates a new contract instance
});
然后,Truffle
就会负责一切。有木有很贴心啊?
-
在初始化
alice
和bob
的代码行下面,让我们来声明一个名为contractInstance
的变量。不要把它分配给任何东西。注意:我们想要
contractInstance
的作用域仅限于定义它的块。使用let
代替var
。 -
接下来,复制/粘贴上面的代码片段,以定义
beforeEach()
函数。 -
现在来填充新函数主体。继续并移动在
beforeEach()
函数中创建新合约实例的代码行。既然我们已经在其他地方定义了contractInstance
,你现在可以删除const
限定符了。 -
我们的测试将需要一个新的
it()
空函数。将测试名(这是传递给it()
函数的第一个参数)赋值为“should not allow two zombies”。
我们将在下一章继续详细讲解这个函数!
如果你真的真的想达到 精通,请继续往下读。否则…… 直接点击下一步,就可以进入下一章了。
还在吗?😁
太棒了!毕竟,有什么理由拒绝让自己变得更优秀呢?
现在,让我们回头看看 contract.new
是如何运行的。基本上,每次我们调用这个函数时,Truffle 都会确保新合约得以部署。
一方面,这很有用,因为它让我们完全从头开始每个测试。
但另一方面,如果每个人都创建无数个合约,区块链将变得臃肿。我们想要你留下来,不是你的旧测试合同!
我们想要阻止这种情况发生,对吧?
幸好,解决方案非常简单…… 我们的合约一旦不再需要就会selfdestruct(自行销毁)
。
其原理如下:
- 首先,我们要添加一个新函数到
CryptoZombies
智能合约,像这样:
function kill() public onlyOwner {
selfdestruct(owner());
}
Note: If you want to learn more about
selfdestruct()
, you can read the Solidity docs here. The most important thing to bear in mind is thatselfdestruct
is the only way for code at a certain address to be removed from the blockchain. This makes it a pretty important feature!
- n接着,与上面解释过的
beforeEach()
函数有点类似,我们将创建一个名为afterEach()
的函数:
afterEach(async () => {
await contractInstance.kill();
});
- 最后, Truffle 将确保在执行测试之后调用此函数。。
瞧,智能合约自动删除了!
在本课中,我们有很多内容要介绍,实现这个特性可能至少还需要两章。我们相信你能做到。💪🏻