Dappのテストを書いているときにイベントのテスト方法が分からなかったので、調べてみました。
結果的にはtruffle-assertions
という外部ライブラリを使うことで何とかできました。ライブラリなしで簡単にできる方法は見つかりませんでした。教えて下さい。
コントラクト
簡単なルーレットアプリを作りました。
0~36までの番号があって、数字が当たったら掛け金の36倍もらえて、色が当たったら掛け金の2倍がもらえるやつです。
コントラクト自体は単純なのでコードは説明文だけ入れておきます。
roulette.sol
// _betは掛け金、 _randNumはルーレットが止まった数字です。
function judgeResult(uint8 _bet, uint8 _randNum) public payable{
if(数字にベットした時){
_betと_randNumが同じだったら36倍の返金
違かったら掛け金没収
}else if(色か偶数、奇数にベットした時){
偶数に賭けていて_randNumが偶数だったら2倍の返金(色とか奇数の場合も)
違かったら賭金没収
}else if (列か1~12とかにベットした場合)
列に賭けていて_randNumがその列だったら3倍の返金(他の条件も)
違かったら賭金没収
}
// 結果をブラウザに表示するためにイベントでルーレットがどこに止まったかと、返金額(もしくは没収)をemitします。
emit JudgeResult(resultNum, returnAmount);
}
truffle-assertionsの導入
公式チュートリアルで説明されている通りに導入します。
npm install --save-dev chai truffle-assertions
chaiは使わなくても私のテストでは問題ありませんでしたが、この辺はよく分からないのでとりあえず入れときました。
テスト
数字が当たったら、ちゃんと掛け金の36倍が返ってくることを確認したいので、下記の様に書きました。
TestRoulette.js
var Roulette = artifacts.require("Roulette");
const assert = require("chai").assert;
const truffleAssert = require('truffle-assertions');
contract("RouletteTest", function(accounts){
it("should be possible to win and get ether (36times)", function(){
var rouletteInstance;
return Roulette.new({from: accounts[0], value: web3.utils.toWei("1", "ether")}).then(function(instance){
rouletteInstance = instance;
return rouletteInstance.judgeResult(5, 5, {value: web3.utils.toWei("0.01", "ether")});
}).then((result) => {
//ファンクションを呼び出したときに発火されるJudgeResultイベントで賭金の36倍がリターンされているか確認する。
truffleAssert.eventEmitted(result, 'JudgeResult', (ev) => {
return ev.returnAmount == web3.utils.toWei("0.36", "ether")
}, 'Contract should return 36 times as much as bet');
}).catch(err => {
console.log(err);
})
});
}
ev.returnAmount == web3.utils.toWei("0.36", "ether")
で厳密等価演算子(===)を使うとテストが通りません。これは、ev.returnAmountがbig numberオブジェクトで、web3.utils.toWei("0.36", "ether")がstring型だからです。