アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

truffleでminer.stopなテストの書き方

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したいということ自体が希なので仕方ないといえばないのですが。。。。。