Я пытаюсь написать тесты в Mocha/JS с Truffle для функции Solidity, которая использует Oraclize. Я хочу проверить правильность результата обратного вызова моего запроса Oraclize. Поскольку Oraclize требуется некоторое время для обработки запроса, мне нужно дождаться ответа транзакции. Прямо сейчас я добиваюсь этого с помощью setTimeout
функции ожидания транзакции обратного вызова. Установка тайм-аута может потребовать от меня ожидания дольше, чем необходимо, или даже привести к сбою теста, если тайм-аут установлен слишком мало. Есть ли лучший способ добиться этого?
Я использую Truffle 3.2.1 с TestRPC 3.0.5 и ethereum-bridge 0.4.21.
Вот фрагмент тестового кода 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();
});
});
Это функция обратного вызова Solidity с newResult
событием:
function __callback(bytes32 _oraclizeID, string _result) {
if (msg.sender != oraclize_cbAddress()) throw;
newResult(_result);
requestOraclize[_oraclizeID].result = _result;
}
Вы можете создать функцию, которая создает часы фильтра для новых tx-s с адреса CB Oraclize. Эта функция может разрешиться, когда новый tx от адреса cb Oraclize соответствует вашим критериям.
Вот пример, который я создал для немного другого требования (т. е. дождаться, пока временная метка блока достигнет определенной временной метки), но вы можете построить его.
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();
});
});