我正在使用Truffle和TestRPC开发以太坊合约。但是我无法获得要更新的状态变量。我认为可能只是因为我太早访问它,但其他示例测试似乎工作得很好并且非常相似。
我已将合同缩减到最简单的可能性:
pragma solidity ^0.4.11;
contract Adder {
uint public total;
function add(uint amount) {
total += amount;
}
function getTotal() returns(uint){
return total;
}
}
这是我的考验:
var Adder = artifacts.require("./Adder.sol");
contract('Adder', accounts => {
it("should start with 0", () =>
Adder.deployed()
.then(instance => instance.getTotal.call())
.then(total => assert.equal(total.toNumber(), 0))
);
it("should increase the total as amounts are added", () =>
Adder.deployed()
.then(instance => instance.add.call(10)
.then(() => instance.getTotal.call())
.then(total => assert.equal(total.toNumber(), 10))
)
);
});
第一次测试通过了。但第二次测试失败,因为getTotal
仍然返回0。
答案 0 :(得分:5)
我认为问题在于您始终使用.call()
方法。
实际上,此方法将执行代码,但不会保存到区块链。
只有在阅读区块链或测试.call()
时才应使用throws
方法。
只需删除添加功能中的.call()
即可。
var Adder = artifacts.require("./Adder.sol");
contract('Adder', accounts => {
it("should start with 0", () =>
Adder.deployed()
.then(instance => instance.getTotal.call())
.then(total => assert.equal(total.toNumber(), 0))
);
it("should increase the total as amounts are added", () =>
Adder.deployed()
.then(instance => instance.add(10)
.then(() => instance.getTotal.call())
.then(total => assert.equal(total.toNumber(), 10))
)
);
});
另外,考虑在promise的函数链之外声明instance
变量,因为不共享上下文。考虑使用async/await进行测试而不是承诺。
var Adder = artifacts.require("./Adder.sol");
contract('Adder', accounts => {
it("should start with 0", async () => {
let instance = await Adder.deployed();
assert.equal((await instance.getTotal.call()).toNumber(), 0);
});
it("should increase the total as amounts are added", async () => {
let instance = await Adder.deployed();
await instance.add(10);
assert.equal((await instance.getTotal.call()).toNumber(), 10);
});
});