Contract-Development

使用 Truffle 進行基本測試(不改變合約狀態)

  • August 22, 2017

我剛剛開始使用 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.fromAsciiweb3.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 上發布了完整的項目以獲取更多詳細資訊。

引用自:https://ethereum.stackexchange.com/questions/24897