//tips
//smart contract
先のテスト確認でインスタンス化を行ったが、毎回テストのたびにconst contractInstance = await CryptoZombies.new();を書くのは面倒なので省略できる。
MochaとTruffleの機能で、effectフックと同様に下記のようなフックでテスト前に必ず実行するようにできる。
beforeEach(async () => {
// let's put here the code that creates a new contract instance
});
contractInstanceを宣言する時にはvarではなくletを使用して、型に制約をかけておくことが必要とのこと。
contract("CryptoZombies", (accounts) => {
let [alice, bob] = accounts;
let contractInstance;
beforeEach(async () => {
contractInstance = await CryptoZombies.new();
});
it("should be able to create a new zombie", async () => {
const result = await contractInstance.createRandomZombie(zombieNames[0], {from: alice});
assert.equal(result.receipt.status, true);
assert.equal(result.logs[0].args.name,zombieNames[0]);
})
//define the new it() function
it("should not allow two zombies", async () => {
})
ここで少しcontract.newの仕組みについて振り返る。
この機能でインスタンス化を行うときtruffleは新規のコントラストをdeployした状態となる。なので、以前にdeployをしたものがどんどん蓄積していってしまう。
なので、不要なコントラクトを削除する際にselfdestructを使用する。これはテストだからできることで、以前確認したselfdestructの危険性(ユーザー側からの目線)について理解しておく。
https://medium.com/loom-network-japanese/%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%B3%E3%83%B3%E3%83%88%E3%83%A9%E3%82%AF%E3%83%88%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-part-2-6ef700df00af
function kill() public onlyOwner {
selfdestruct(owner());
}
次にテストで一人一つしかゾンビができないことを確認する。
条件に追加しているだけ。utilはhelperから使用したい機能を引っ張ってきている。
const utils = require("./helpers/utils");
it("should be able to create a new zombie", async () => {
const result = await contractInstance.createRandomZombie(zombieNames[0], {from: alice});
assert.equal(result.receipt.status, true);
assert.equal(result.logs[0].args.name,zombieNames[0]);
})
it("should not allow two zombies", async () => {
await contractInstance.createRandomZombie(zombieNames[0], {from: alice});
await utils.shouldThrow(contractInstance.createRandomZombie(zombieNames[1], {from: alice}));
})
また、assertは、例外処理として、throwとrevertでコントラクトに対する処理を全て取り消すことができ、トランザクション処理の前の状態に戻す。
assert(true);の場合は、boolの設定と似ており、falseとのセットで使われるよう。falseで定義すことで、コメントを表示できる。
assert(false, "The contract did not throw.");
さらにtransferの部分のテストも加える。transferでは以前2パターンあったと思うが、複雑な場合にはテストも複数のitを持つことになる。
なので、機能をグループ単位でテストする方法として、Truffleはcontextという複数itをグループにしてテストする仕組みを設けている。
また、テスト部分を絞るには先頭にxをつけることでテストから除外することができる。
xcontext("with the single-step transfer scenario", async () => {
it("should transfer a zombie", async () => {
// start here.
})
})