Implementierung von Oraclize-Callback-Tests mit Truffle/Mocha

Ich versuche, Tests in Mocha/JS mit Truffle für eine Solidity-Funktion zu schreiben, die Oraclize verwendet. Ich möchte testen, ob das Ergebnis im Callback meiner Oraclize-Abfrage korrekt ist. Da Oraclize einige Zeit benötigt, um die Abfrage zu verarbeiten, muss ich auf die Antwort der Transaktion warten. Im Moment erreiche ich dies mit einer setTimeoutFunktion, um auf die Callback-Transaktion zu warten. Durch das Festlegen eines Timeouts muss ich möglicherweise länger als nötig warten oder der Test schlägt sogar fehl, wenn das Timeout zu niedrig eingestellt ist. Gibt es einen besseren Weg, dies zu erreichen?

Ich verwende Truffle 3.2.1 mit TestRPC 3.0.5 und Ethereum-Bridge 0.4.21.

Hier ist das JS-Testcode-Snippet:

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();
  });
});

Dies ist die Solidity-Callback-Funktion mit einem newResultEreignis:

function __callback(bytes32 _oraclizeID, string _result) {
  if (msg.sender != oraclize_cbAddress()) throw;
  newResult(_result);
  requestOraclize[_oraclizeID].result = _result;
}

Antworten (1)

Sie könnten eine Funktion erstellen, die eine Filterüberwachung für neue TX-s von der CB-Adresse von Oraclize erstellt. Diese Funktion könnte aufgelöst werden, wenn eine neue tx von der cb-Adresse von Oraclize Ihren Kriterien entspricht.

Hier ist ein Beispiel, das ich für eine etwas andere Anforderung erstellt habe (z. B. warten, bis der Blockzeitstempel einen bestimmten Zeitstempel erreicht), aber Sie könnten daraus bauen.

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();
    });
});