0

and am trying to write some test for a payable function in Solidity but i don't know how to go about it any help will be appreciated . I want to test for the case where the buyer send an amount less of the item price . should i just check if the state of the item hasn't changed or is there a way to check if the modifier didn't "Pass"

modifier checkValue(uint _sku) {
    _;
    uint _price = items[_sku].price;
    uint amountToRefund = msg.value - _price;
    items[_sku].buyer.transfer(amountToRefund);
}
modifier paidEnough(uint _price) {require(msg.value >= _price);_;}    

function buyItem(uint _sku) forSale (_sku) checkValue(_sku) paidEnough(items[_sku].price) public payable
{
    items[_sku].buyer = msg.sender;
    items[_sku].seller.transfer(items[_sku].price);
    items[_sku].state = State.Sold;
    emit Sold(_sku);
}
1

It's important to test not only that the contract does what it should, but also that it never does anything it shouldn't.

In other words, you can and you should test for cases where you expect the contract to throw an exception.

Consider:

it("should fail", async() => {
  try {
    const tx = await instance.doSomethingWrong();
    assert.equal(tx, undefined, "this should not happen");
  } catch (error) {
    assert.equal(error.message, "VM Exception while processing transaction: revert");
  }
});

Have a look also at Xavier's excellent implementation: https://gist.github.com/xavierlepretre/d5583222fde52ddfbc58b7cfa0d2d0a9

Hope it helps.

  • Thank you for your answer , am looking to learn how to use truffle for testing using Solidity test , i have tests writing in JS . ideally i want to learn coding tests in Solidity. If you can point me to some resources to look or any repo i I would be grateful. and is there a way to know which modifier throw the exception , my function use 2 modifier and ideally i want to test them separately for different conditions . – Mero Dec 4 '18 at 22:39
  • 1
    My knowledge of .sol tests is somewhat limited. I use JavaScript (the original) to test solidity contracts. Assert.sol is an alternative. This is perhaps not as prescriptive as you would like but the fundamental hurdle is the atomicity of EVM transactions because you want to trigger an exception, but you want the test to carry on. call() methods (solidity) will return false in the case that the called contract throws an exception. You might assert that this is the case. Warning: ethereum.stackexchange.com/questions/8270/… – Rob Hitchens - B9lab Dec 4 '18 at 23:47
  • Thanks a lot for your insight , i think using "truffle/deployedContract.sol" you can create an instance of the Contract and call the methods directly avoiding the call() i will have to look more into this . – Mero Dec 5 '18 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.