Javascript
使用 Truffle 進行 JavaScript 和 Solidity 測試之間相同合約的不同行為
我有一個簡單的合約,它的作用是作為利率管理員——它是用容量和 time_frame(以塊為單位)參數構造的,並確保我們在任何給定的時間範圍內不會添加超過 $capacity 的付款。如果我們沒有超出容量,函式 addPayment() 會註冊支付的時間戳並將負載加一。否則它將返回 false 。
pragma solidity >=0.5.8 <0.6.0; contract RateKeeper { uint256 public capacity; uint256 public timeframe; uint256 public load; // Number of transactions in record so far constructor (uint256 _capacity, uint256 _timeframe) public { capacity = _capacity; timeframe = _timeframe; load = 0; } function addPayment() public onlyOwner returns (bool added) { // removeOldEntries(); if (load >= capacity){ return false; } load++; return true; }
當我在solidity 中測試該函式時,它的行為符合預期,但是在JavaScript 中,負載不會隨著函式呼叫而增加。這是為什麼?
在以下 JavaScript 測試中,最後兩個斷言失敗:
contract("JS RateKeeper test", async accounts => { it("Constructor, addPayment(). This test doesn't pass", async function () { let instance = await RateKeeper.new(1, 299); let inst_capacity = await instance.capacity.call(); assert.equal(inst_capacity, 1); let load = await instance.load.call(); assert.equal(load, 0, "load is 0 as no payments were initiated so far"); let payment_success = await instance.addPayment.call(); assert(payment_success, "Load is 0, capacity is 1 - payment should succeed"); let load2 = await instance.load.call(); assert.equal(load2, 1, "load should be 1 after a single call to addPayment()"); payment_success = await instance.addPayment.call(); assert(!payment_success, "We are at full capacity, payment should fail");
同時,堅固性測試進展順利
function testAddPayment() public{ RateKeeper keeper = new RateKeeper(2,299); Assert.equal(keeper.load(), 0, "We added no payments"); Assert.isTrue(keeper.addPayment(), "Contract has (0/2) payments"); Assert.equal(keeper.load(), 1, "We added 1 payment"); Assert.isTrue(keeper.addPayment(), "Contract has (1/2) payments"); Assert.equal(keeper.load(), 2, "We added 2 payment"); Assert.isFalse(keeper.addPayment(), "Contract has (2/2) payments"); Assert.equal(keeper.load(), 2, "We added 2 payment"); Assert.isFalse(keeper.addPayment(), "Contract has (2/2) payments"); Assert.equal(keeper.load(), 2, "We added 2 payment"); keeper.destroy();
這是由於 的行為
call()
。Call
是只讀的,例如在函式中所做的任何狀態更改都不是持久的。如果您更改instance.addPayment.call()
to的實例instance.addPayment()
,它將保留更改。當然,還有另一個複雜情況,即您使用的是 的返回值
addPayment
,這對於持久更改並不真正起作用。您將不得不恢復錯誤或添加日誌語句以查看外部發生的情況。