Testing 测试智能合约需要在Truffle中:如果函数不无效,事务将恢复

Testing 测试智能合约需要在Truffle中:如果函数不无效,事务将恢复,testing,ethereum,solidity,truffle,Testing,Ethereum,Solidity,Truffle,根据本文,我尝试使用刚稳定度测试智能合约的要求: 这是合同、抛出代理合同和测试: /* Testing with solidity tests. */ import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import "../contracts/MyContract.sol"; contract TestMyContract { function testInitialStoredValue() {

根据本文,我尝试使用刚稳定度测试智能合约的要求:

这是合同、抛出代理合同和测试:

/* Testing with solidity tests. */

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/MyContract.sol";

contract TestMyContract {

function testInitialStoredValue() {
    MyContract mycontract = new MyContract();

    uint expected = 24;

    Assert.equal(mycontract.mynumber(), expected, "First number set should be 24.");
}

function testTheThrow() {
    MyContract mycontract = new MyContract(); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 
    uint num = 7;
    MyContract(address(throwproxy)).storeNum(num);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isFalse(r, "Should be false because is should throw!");

}

function testNoThrow() {
    MyContract mycontract = new MyContract(); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 

    MyContract(address(throwproxy)).storeNum(22);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isTrue(r, "Should be true because is should throw!");

}

}

// Proxy contract for testing throws
contract ThrowProxy {
  address public target;
  bytes data;

  function ThrowProxy(address _target) {
    target = _target;
  }

  //prime the data using the fallback function.
  function() {
    data = msg.data;
  }

  function execute() returns (bool) {
    return target.call(data);
  }
}
如果运行测试,则会出现以下错误:

如果我将storeNum函数从更改为void

 function storeNum(uint mynum)
        public
        returns (bool)
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }

测试是有效的

有什么想法吗


我正在使用Truffle v4.1.11

让我们看看您的代码:

function storeNum(uint mynum)
        public
        returns (bool success)
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }
通过定义
返回(bool success)
您对solidity编译器说了两件事:

  • 有一个名为
    success
    的变量,其类型为
    bool
    (变量定义)
  • 该变量success将由函数返回(返回定义)
但是变量毕竟不会返回(函数以
return true
结尾,这就是为什么测试中会出现InvalidResponse错误

对于您的代码,最有效的代码是:

function storeNum(uint mynum)
        public
        returns (bool)    // you should define at least the type
    {
     require(mynum > 10);
     mynumber = mynum; 
     return true;    
    }
作为练习,使用变量
success

function storeNum(uint mynum)
        public
        returns (bool success)
    {
     require(mynum > 10);
     mynumber = mynum; 
     success = true;    // don't need to use return
    }

希望能有所帮助。

好吧,我已经向Truffle github提交了一个问题,它仍然开放,也许这与最近的坚固性变化有关:

目前的一项工作是将函数包装成无效函数,并测试执行是否成功:

/*
    Contract wrapper that inherits from MyContract. This contract wraps the calls of non void functions when
    testing for exceptions.

    Why not invoke directly the function?: https://github.com/trufflesuite/truffle/issues/1001
*/

contract MyExposedContract is MyContract() {


    function callStoreNum(uint256 num)  public {
        storeNum(num);
    }

}
然后在测试中使用该包装器:

function testTheThrow() {
    MyExposedContract mycontract = new MyExposedContract (); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 
    uint num = 7;
    MyExposedContract (address(throwproxy)).callStoreNum(num);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isFalse(r, "Should be false because it should throw!");

}

您好,我理解,但这似乎不是问题的原因,我收到了相同的错误。我认为此链接将对您有很大帮助:事实上,这就是我举的例子。我正在尝试使用Solidity v0.5包装类的这种解决方法,但它不起作用。此外,在包装中定义
callStoreNum
,但在测试中您仍在呼叫
storeNum
。尚未尝试使用solidity 0.5。谢谢,我已修复了答案
function testTheThrow() {
    MyExposedContract mycontract = new MyExposedContract (); 

    ThrowProxy throwproxy = new ThrowProxy(address(mycontract)); 
    uint num = 7;
    MyExposedContract (address(throwproxy)).callStoreNum(num);

    bool r = throwproxy.execute.gas(200000)(); 

    Assert.isFalse(r, "Should be false because it should throw!");

}