The โmost correctโ solution to this problem that I could come up with is checking all the sent gas that occurs during the throw, but there is an additional wrinkle to make the solution work like on TestRPC (which, I assume, you are using, given the actual error ) and Geth. When a throw occurs in Geth, the transaction is still created, posting all the gas, but no state changes occur. TestRPC really throws an error, which is useful for debugging purposes.
//Somewhere where global functions can be defined function checkAllGasSpent(gasAmount, gasPrice, account, prevBalance){ var newBalance = web3.eth.getBalance(account); assert.equal(prevBalance.minus(newBalance).toNumber(), gasAmount*gasPrice, 'Incorrect amount of gas used'); } function ifUsingTestRPC(){ return; } //Some default values for gas var gasAmount = 3000000; var gasPrice = 20000000000; .... //Back in your actual test it('should fail ', function (done) { var prevBalance; .... .then(function (_bool0) { assert.isTrue(_bool0,"whoops - should be true"); prevBalance = web3.eth.getBalance(accounts[1]); return contract.do( "okdoke" , {from: accounts[1], gasPrice:gasPrice, gas:gasAmount } ); }) .catch(ifUsingTestRPC) .then(function(){ checkAllGasSpent(gasAmount, gasPrice, accounts[1], prevBalance); }) .then(done) .catch(done);
I would happily implement a simpler solution if another appears.
NB If you spend all gas on a transaction that is random, this will not be noticed - it is assumed that the gas was consumed due to a throw inside the virtual machine.
source share