Truffleでちょっと特殊(?)なテストを書こうとしたら思ったよりもハマってしまったので、備忘録的に残しておきます。
miner.stopしたら動かないテスト
書きたかったテストとしては、同一ブロックに複数のtransactionが含まれていた場合のテストです。
で、そのテストを素直に書くと、次のようになります。
gist.github.com
で、このテストは動きません。11行目の `await instance.transfer(accounts[1], 100)`のところでフリーズします。
miner.stopするとsendTransactionでフリーズする理由
原因としては、@truffle/contractを用いて、contractの関数を呼び出すと、truffle側で自動的にTransactionReceiptを取得しようとします。truffleはTransactionReceiptが取得できない間はなんども、`eth_getTransactionReceipt`を発行するため、ここで無限ループに陥ってフリーズしてしまうのです。
miner.stopでフリーズしないテスト
これを回避する方法を色々と試してみたのですが、どうやら、`web3.eth.sendTransaction` メソッド自体もオーバーライドされているらしくどうにも回避ができませんでした。
最終的に`web3.eth.HttpProvider#send`を直接呼ぶことで回避しました。
ということで、miner.stopした状態でうまく動作するテストは次のように書くと良いです。
gist.github.com
まとめ
@truffle/contractがTransactionReceiptが取得できるまで待つかどうかのフラグをオプションとして持っていればよかったのですが、そのようなオプションがないので、ちょっとまどろっこしい形での回避策となってしまいました。
まぁ、そもそもテスト中にminer.stopしたいということ自体が希なので仕方ないといえばないのですが。。。。。