Wie man Strukturwerte testet

Ich bin neu in der Solidity-Entwicklung und versuche herauszufinden, wie ich eine Funktion am besten testen kann, die die Werte einer Struktur in meiner Truffle-Umgebung festlegt.

Erstens wird erwartet, dass das Ergebnis des Versprechens im folgenden Format zurückgegeben wird:

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

Und wenn ja, ist dies das richtige Muster, um zu testen, ob die richtige Eigenschaft von der Setter-Methode festgelegt wurde (in diesem Fall Name: John):assert.equal(res[1], "John");

Unten sehen Sie den Beispielvertrag, den ich zu testen versuche:

./verträge/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;
}        

}

./test/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");
  });

Antworten (2)

Leider waren Strukturen nicht Teil der ursprünglichen Soliditäts- ABI-Spezifikation , sodass sie stattdessen ein Tupel von Werten zurückgeben.

Ein weiteres Problem ist, dass Javascript Integer nicht mit ausreichender Genauigkeit unterstützt. Um Probleme wie Genauigkeitsverlust oder Rundungsfehler zu vermeiden, wird web3 Ganzzahlen in Objekte umschließen BigNumber, siehe Was sind *C*-, *E*- und *S*-Eigenschaften im Nachrichtenaufruf-Rückgabeobjekt? für andere Details.

Um BigNumbers zu vergleichen, können Sie sie mit in gewöhnliche Javascript-Zahlen umwandeln .toNumber()(dies funktioniert nur für kleine Ganzzahlen https://stackoverflow.com/questions/307179/what-is-javascripts-highest-integer-value-that-a-number- can-go-to-within-losin ), für große Zahlen ist es wahrscheinlich am besten, sie in eine Zeichenfolge zu konvertieren oder einige der Methoden aus der BigNumberBibliothek zu verwenden.

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");
  });

Sie können die Werte einer Struktur dekonstruieren, wenn Sie Komponententests in Hardhat durchführen. Wenn Sie in Ihrem Beispiel das Alter und den Namen aus einer Struktur abrufen möchten, lautet der Code:

let [Alter, Name] = contractInstance.dogs()

Die ID wäre die Position des Hundes, den Sie möchten. Dann sollten Sie wie gewohnt die Alters- oder Namensvariablen mit Ihrer Eingabe vergleichen können.