Solidity
您如何使用 truffle 和 ethereum-testRPC 處理合約測試中的預期投擲?
是否可以使用 truffle 編寫一個測試來嘗試確認合約中發生了拋出?例如,如果我有一個功能契約……
contract TestContract { function testThrow() { throw; } }
如果我在 truffle 中編寫一個呼叫此函式的測試,那麼 truffle 測試基本上會崩潰:
Error: VM Exception while executing transaction: invalid JUMP
有沒有辦法在你的測試中處理這個異常來驗證拋出是否真的發生了?我想這樣做的原因是測試當使用者傳入無效輸入時我的函式是否實際拋出?
您可以使用 OpenZeppelin 的 expectThrow 助手 -
來源:https ://github.com/OpenZeppelin/zeppelin-solidity/blob/master/test/helpers/expectThrow.js
export default async promise => { try { await promise; } catch (error) { // TODO: Check jump destination to destinguish between a throw // and an actual invalid jump. const invalidJump = error.message.search('invalid JUMP') >= 0; // TODO: When we contract A calls contract B, and B throws, instead // of an 'invalid jump', we get an 'out of gas' error. How do // we distinguish this from an actual out of gas event? (The // testrpc log actually show an 'invalid jump' event.) const outOfGas = error.message.search('out of gas') >= 0; assert( invalidJump || outOfGas, "Expected throw, got '" + error + "' instead", ); return; } assert.fail('Expected throw not received'); };
我像這樣使用它的測試案例-
import expectThrow from './helpers/expectThrow'; . . . describe('borrowBook', function() { it("should not allow borrowing book if value send is less than 100", async function() { await lms.addBook('a', 'b', 'c', 'e', 'f', 'g'); await lms.addMember('Michael Scofield', accounts[2], "Ms@gmail.com"); await lms.borrowBook(1, {from: accounts[2], value: 10**12}) await expectThrow(lms.borrowBook(1, {from: accounts[2], value: 10000})); // should throw exception }); });