Truffle

使用 Truffle/Mocha 實現 Oraclize 回調測試

  • January 2, 2019

我正在嘗試使用 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();
   });
});

引用自:https://ethereum.stackexchange.com/questions/15782