Contract-Development
使用 Truffle 進行基本測試(不改變合約狀態)
我剛剛開始使用 Truffle 來測試這個合約
pragma solidity ^0.4.11; contract Basic { bytes32 value; function Basic() { value = "mcansado"; } function getValue() constant returns(bytes32) { return value; } function setValue(bytes32 _value) constant returns(bytes32) { value = _value; } }
相關的測試程式碼是
it("Should set value to 40", function(done) { basic.setValue(40, {from:accounts[0], to:basic.address}) .then(function(tx) { console.log(tx) //assert.isOk(tx.receipt) done() }, function(error) { assert.equal(true, false) console.error(error) done() }) })
那個測試後面跟著一個就搞定了
value
。我希望得到 40 回來,但我得到了這個輸出Contract: Basic 0x7d32e47118fbc082af1350062f10efee2694ff15 ✓ Should retrive deployed contract. 0x0000000000000000000000000000000000000000000000000000000000000000 ✓ Should set value to 40 (43ms) mcansado // returns the value made by constructor, not 40 ✓ Should return the value set as 40 3 passing (114ms)
如何在測試中發送新值?
您的契約和測試中有幾個問題:
- Solidity 合約
您必須將呼叫(只讀方法)與事務(更改狀態的寫入方法)區分開來。關鍵字
constant
用於將方法指定為 readOnly,這意味著不操作任何狀態變數。此外,交易始終是非同步的,因為交易需要首先廣播到 peer2p 網路,然後由礦工探勘,這可能需要時間(尤其是在真實網路上,例如測試網或主網)。
因此,當您從外部發送交易(Web3 和 Truffle)時,您不能期望返回任何值。
契約看起來像這樣:
pragma solidity ^0.4.11; contract Basic { bytes32 value; function Basic() { value = "mcansado"; } function getValue() constant returns(bytes32) { return value; } function setValue(bytes32 _value) { value = _value; } }
- 松露測試
其次,您的測試不正確,因為您不能期望交易返回值,您需要
getValue.call()
在交易發送後呼叫。另一種認為,用
byte32
類型,你必須處理十六進制值。所以你必須使用 web3 函式web3.fromAscii
和web3.toAscii
.最後一點,可以直接呼叫
Basic.deployed()
獲取部署的實例。我調整了你的測試:
var Basic = artifacts.require("./Basic.sol"); contract('Basic', function(accounts) { var basic; it("Should set value to 40", function() { return Basic.deployed().then(function(instance) { // Get deployed contract basic = instance; return basic.getValue.call(); // call getValue function }).then(function(result) { console.log("#######################"); console.log("result (hexa)=" + result); // in hexa console.log("result (ascii)=" + web3.toAscii(result)); // in ascii return basic.setValue(web3.fromAscii("40"), {from: accounts[0]}); // send transaction setValue function }).then(function(receipt) { console.log("#######################"); console.log("transaction receipt"); console.log(receipt); return basic.getValue.call(); // call getValue function }).then(function(result) { console.log("#######################"); console.log("result (hexa)=" + result); // in hexa console.log("result (ascii)=" + web3.toAscii(result)); // in ascii assert.equal(web3.toAscii(result), "40"); }); }); });
結果如下:
Contract: Basic ####################### result (hexa)=0x6d63616e7361646f000000000000000000000000000000000000000000000000 result (ascii)=mcansado ####################### transaction receipt { tx: '0x051654a9fc0aaeb44ff54229c31ab91e9ad9fe9b03da4498d978740e760d739c', receipt: { transactionHash: '0x051654a9fc0aaeb44ff54229c31ab91e9ad9fe9b03da4498d978740e760d739c', transactionIndex: 0, blockHash: '0x106da8c6862f2caf94d40cf866d4b9a61b9c7839d7608fab00e114700dc3eb93', blockNumber: 108, gasUsed: 26695, cumulativeGasUsed: 26695, contractAddress: null, logs: [] }, logs: [] } ####################### result (hexa)=0x3430000000000000000000000000000000000000000000000000000000000000 result (ascii)=40
我在GitHub 上發布了完整的項目以獲取更多詳細資訊。