我的合约有多个云函数,我正在尝试使用 sinon 创建一些单元测试。但是,我在尝试模拟某些云功能时遇到了问题。我只想存根它们,并在方法中调用智能合约的一些属性并希望它返回指定的值。为了理解我在做什么,这里是合同的代码片段(部分):
contract RoundOracle is Ownable, AccessControl, Pausable {
uint8 public round; // Starts from 1. Updated after each round has finished.
uint8 public constant START = 0;
uint8 public constant END = 1;
event LogSetRoundBounds(uint8 round, uint256 startRound, uint256 endRound);
constructor() {
round = 1;
}
}
然后我想对这个属性进行存根并断言它的值等于2,它给了我前面提到的错误。这是代码:
describe("NFT Rounds Test", () => {
context("NFT Rounds positive testing", () => {
before(function () {
initializeENV();
});
after(function () {
sandbox.restore();
});
it.only("Test the web3 calls", async() => {
console.log("hit b4 web3");
var web = Web3.getInstance();
console.log("hit after web3")
var newSandbox = sinon.createSandbox();
newSandbox.stub(web.roundOracle, "round").value(2);
expect(web.roundOracle.round).to.equal(2, "not equal to 2");
console.log("finally passed this stubbing ---");
});
});
});
我知道这是因为该属性不可写,但是即使它们不可写或可配置,是否可以以某种方式测试此类场景?
我想出了如何解决这个问题。首先,我删除了对象(清除它们),然后定义新属性,然后在模拟时,只需返回所需的值。
// remove the desired objects (properties/functions)
removeRef(name, object) {
for (let i = 0; i < this[name].length; i++) {
delete object[this[name][i]];
}
for (let i = 0; i < this[name].length; i++) {
object[this[name][i]] = {};
}
}
// setting the function callback and the properties that I want to be true
mockFunction(o, k, cb) {
Object.defineProperty(o, k, {
enumerable: true,
value: cb,
writable: true,
configurable: true,
});
}
之后,我只是在 before() 钩子中调用removeRef,然后在测试函数中这样调用它:
prerequisites.mockFunction(<object-instance>, "<method/property-name>", () => "hash");
对象实例=声明属性和函数的类。