什么是测试完成链连接oracle请求醚/硬帽的最佳实践?



我正在使用硬帽和以太坊在冰场上测试一个智能合约,该合约向本地链链节点发出一个get请求。我可以在节点仪表板上观察到请求已经完成。

我正在努力编写一个等待第二次履行事务得到确认的测试。

我在SmartContractKit/chainlink repo测试中看到类似的测试

it("logs the data given to it by the oracle", async () => {
const tx = await oc.connect(roles.oracleNode).fulfillOracleRequest(...convertFufillParams(request, response));
const receipt = await tx.wait();
assert.equal(2, receipt?.logs?.length);
const log = receipt?.logs?.[1];
assert.equal(log?.topics[2], response);
});

我看不出这将等待完成的事务。在消费者中。当这个函数调用时,有一个事件requestcompleted,也就是emit,但是这个测试似乎并没有监听它。

我发现的另一个例子是ocean协议请求测试,它通过创建请求id的映射、访问器和测试轮询中的while循环来实现这一点,直到找到请求id。

it("create a request and send to Chainlink", async () => {
let tx = await ocean.createRequest(jobId, url, path, times);
request = h.decodeRunRequest(tx.receipt.rawLogs[3]);
console.log("request has been sent. request id :=" + request.id)
let data = 0
let timer = 0
while(data == 0){
data = await ocean.getRequestResult(request.id)
if(data != 0) {
console.log("Request is fulfilled. data := " + data)
}
wait(1000)
timer = timer + 1
console.log("waiting for " + timer + " second")
}
});

这是有道理的,我知道它是如何工作的。但是,当我认为有一种更优的方法时,我希望避免创建映射和访问器。

您需要查看hardhat-starter-kit以查看使用Chainlink/oracle API响应的示例。

对于单元测试,您只需要模拟来自Chainlink节点的API响应。

对于集成测试(例如,在测试网络上),您将为返回添加一些等待参数。在样例hardhat-starter-kit中,它只等待x秒,但是您也可以编写测试来侦听事件,以了解oracle何时响应。这确实使用事件来获取requesttid,然而,你实际上不需要自己创建一个事件,因为Chainlink核心代码已经有了这个。

it('Should successfully make an external API request and get a result', async () => {
const transaction = await apiConsumer.requestVolumeData()
const tx_receipt = await transaction.wait()
const requestId = tx_receipt.events[0].topics[1]
//wait 30 secs for oracle to callback
await new Promise(resolve => setTimeout(resolve, 30000))
//Now check the result
const result = await apiConsumer.volume()
console.log("API Consumer Volume: ", new web3.utils.BN(result._hex).toString())
expect(new web3.utils.BN(result._hex)).to.be.a.bignumber.that.is.greaterThan(new web3.utils.BN(0))
})