Truffle
使用 Truffle/Mocha 實現 Oraclize 回調測試
我正在嘗試使用 Truffle 在 Mocha/JS 中為使用 Oraclize 的 Solidity 函式編寫測試。我想測試我的 Oraclize 查詢回調中的結果是否正確。由於 Oraclize 需要一些時間來處理查詢,我需要等待事務的響應。現在我正在通過一個
setTimeout
等待回調事務的函式來實現這一點。設置超時可能需要我等待更長的時間,或者如果超時設置得太低,甚至會使測試失敗。有沒有更好的方法來實現這一目標?我正在使用帶有 TestRPC 3.0.5 和 ethereum-bridge 0.4.21 的 Truffle 3.2.1。
這是JS測試程式碼片段:
it("Request computation and send results to Arbiter", function(done) { this.timeout(250000); var computation; var result; ComputationService.deployed().then(function(instance) { computation = instance; return computation.compute("43543", "423543543", 0, 56347573485346, {from:accounts[0], gas: 500000, value: web3.toWei(0.01, "ether")}); }).then(function(){ return new Promise(resolve => setTimeout(resolve, 240000)); }).then(function(){ return computation.getResult(56347573485346); }).then(function(value){ result = value; assert.equal(result, "18442356492849", "The result is wrong (should be 18442356492849)"); done(); }); });
這是帶有
newResult
事件的 Solidity 回調函式:function __callback(bytes32 _oraclizeID, string _result) { if (msg.sender != oraclize_cbAddress()) throw; newResult(_result); requestOraclize[_oraclizeID].result = _result; }
您可以創建一個函式,為來自 Oraclize 的 CB 地址的新 tx-s 創建一個過濾器監視。當來自 Oraclize 的 cb 地址的新交易符合您的條件時,該功能可以解決。
這是我為稍微不同的要求創建的範例(即等待塊時間戳達到某個時間戳),但您可以從中建構。
var moment = require('moment'); function waitForTimeStamp(waitForTimeStamp) { var currentTimeStamp = moment().utc().unix(); var wait = waitForTimeStamp - currentTimeStamp; wait = wait < 0 ? 0 : wait; console.log("... waiting ", wait, "seconds then sending a dummy tx for blockTimeStamp to reach time required by test ..."); return new Promise( resolve => { setTimeout(function () { var blockTimeStamp = web3.eth.getBlock( web3.eth.blockNumber).timestamp; if( blockTimeStamp < waitForTimeStamp ) { web3.eth.sendTransaction({from: web3.eth.accounts[0]}, function(error, res) { if (error) { console.log("waitForTimeStamp() web3.eth.sendTransaction() error") reject(error); } else { resolve(); } }); } else { resolve(); } }, wait * 1000); }); } // waitForTimeStamp() it("should happen in the future", () => { // your instance setup here... return myInstance.myTransaction() .then( res => { var waitLength = res; // in seconds var waitUntil = moment().utc().unix() + waitLength; return waitForTimeStamp(waitUntil); }).then( res => { done(); }); });