Search code examples
testingethereumsoliditysmartcontractstruffle

How to test payable method in truffle?


I'm trying to test smart contract's payable method in truffle framework:

contract Contract {
  mapping (address => uint) public balances;

  function myBalance() public view returns(uint) {
    return balances[msg.sender];
  }

  function deposit() external payable {
    balances[msg.sender] += msg.value;
  }
}

contract TestContract {

  function testDeposit() external payable {
    Contract c = new Contract();

    c.deposit.value(1);

    Assert.equal(c.myBalance(), 1, "#myBalance() should returns 1");
  }
}

After I run truffle test, it's fails with TestEvent(result: <indexed>, message: #myBalance() should returns 1 (Tested: 0, Against: 1)) error. Why?


Solution

  • Your test contract has a couple issues. The first is you're not initializing your test contract to hold any ether. Therefore, there are no funds held by the TestContract to send to Contract. To do this, you need to set an initialBalance contract storage variable (see Testing ether transactions).

    Second, you're not calling your deposit function correctly. To call a function and send ether, the format is contract.functionName.value(valueInWei)(<parameter list>).

    Here is the fixed version of TestContract:

    contract TestContract {
      uint public initialBalance = 1 wei;
    
      function testDeposit() external payable {
        Contract c = new Contract();
    
        c.deposit.value(1)();
    
        Assert.equal(c.myBalance(), 1, "#myBalance() should returns 1");
      }
    }