Как юнит-тестировать значения структуры

Я новичок в разработке Solidity и пытаюсь найти лучший способ протестировать функцию, которая устанавливает значения структуры в моей среде Truffle.

Во-первых, ожидается ли, что результат обещания вернется в следующем формате:

[ BigNumber { s: 1, e: 0, c: [ 5 ] }, 'John' ]

И если это так, это правильный шаблон для проверки правильного свойства, установленного методом установки (в данном случае имя: Джон):assert.equal(res[1], "John");

Ниже приведен пример контракта, который я пытаюсь протестировать:

./контракты/Adoption.sol:

contract Adoption {

struct Dog {
    uint age;
    string name;
}

Dog[] public dogs;

function createDog(uint _age, string _name) public {
    dogs.push(Dog(_age, _name)) - 1;
}        

}

./тест/Adoption.js

return Adoption.deployed()
  .then(function(instance) {
    instance.createDog(5, "John");
    return instance.dogs(0);
  })
  .then(function(res) {
    // dog age should equal 5
    assert.equal(res[0], 5);
    // dog name should equal John
    assert.equal(res[1], "John");
  });

Ответы (2)

К сожалению, структуры не были частью исходной спецификации Solidity ABI , поэтому они будут возвращать кортеж значений.

Другая проблема заключается в том, что javascript не поддерживает целое число с достаточной точностью. Чтобы избежать таких проблем, как потеря точности или ошибки округления, web3 будет переносить целые числа в объекты BigNumber, см. Что такое свойства *C*, *E* и *S* в возвращаемом объекте вызова сообщения? для других деталей.

Чтобы сравнить BigNumbers, вы можете преобразовать их в обычные числа javascripts .toNumber()(это будет работать только для небольших целых чисел https://stackoverflow.com/questions/307179/what-is-javascripts-highest-integer-value-that-a-number- can-go-to-without-losin ), для больших чисел, вероятно, лучше всего преобразовать в строку или использовать некоторые методы из BigNumberбиблиотеки.

return Adoption.deployed()
  .then(function(instance) {
    instance.createDog(5, "John");
    return instance.dogs(0);
  })
  .then(function(res) {
    // dog age should equal 5
    assert.equal(res[0].toNumber(), 5);
    // dog name should equal John
    assert.equal(res[1], "John");
  });

Вы можете деконструировать значения структуры при выполнении модульных тестов в Hardhat. В вашем примере, если вы хотите получить возраст и имя из структуры, тогда код будет таким:

пусть [возраст, имя] = ContractInstance.dogs()

Идентификатор будет позицией собаки, которую вы хотели бы. Затем вы должны иметь возможность сравнивать переменные возраста или имени с вашим вводом, как обычно.