Testen von Vertragsinteraktionen mit Truffle

Ich habe 2 Verträge, Benutzer und Registrierung, die interagieren, und ich möchte ihre Interaktionen mit Truffle testen. Aktuell sind meine Test(s) für User

contract('User', function(accounts) {
  // many tests here which only depend on User contract
})

Ich möchte nun das Zusammenspiel zwischen dem Nutzungsvertrag und einem Registry-Vertrag testen. Die relevanten Teile von jedem sind

Benutzer.sol

pragma solidity ^0.4.11;

import "./Registry.sol";

contract User { 
    address owner;
    address reg;
    bool verified;
    Registry registry = Registry(reg);

    // Register in the system
    function register(bytes32 _id)
        onlyOwner
    {
        registry.register(_id);
    }
    function getContractAddress(bytes32 _id)
        onlyOwner
    {
        registry.getContractAddress(_id);
    }
    function getPublicAddress(bytes32 _id)
        onlyOwner
    {
        registry.getPublicAddress(_id);
    }
    function verify()
        onlyReg
    {
        verified = true;
    }
}

Registry.sol

pragma solidity ^0.4.11;

import "./User.sol";

contract Registry {
    mapping(bytes32 => address) ID;
    mapping(address => address) Contract;

    function register(bytes32 _id) {
        ID[_id] = tx.origin;
        Contract[tx.origin] = msg.sender;
    }

    function getPublicAddress(bytes32 _id) constant returns (address) {
        return (ID[_id]);
    }

    function getContractAddress(bytes32 _id) constant returns (address) { 
        return Contract[ID[_id]];
    }   

    function verify() {
        User requester = User(msg.sender);
        requester.verify();
    }
}

Wie kann ich einen Test schreiben, in dem die Registrierung bereitgestellt wird, damit ich dann register(), getContractAddress(), usw. testen kann?

Ich habe mir die Dokumentation angesehen , aber dort keine Beispiele gefunden.

BEARBEITEN: Nur zur Ergänzung der gegebenen Antwort

Ich habe dies hinzugefügt

contract('User', function(accounts) {
  var user 
  var registry // new part based on your answer
  Registry.new().then((inst) => {
    registry = inst;
  })

  // Check contract was deployed
  it("Should retrieve deployed contract", function(done) {
      // test
  })

Es funktioniert und weiter unten habe ich einen Test zum Festlegen / Abrufen der Registrierungsadresse, der einwandfrei funktioniert (was bedeutet, dass die Adresse bereits vorhanden ist, wenn ich eine Methode im Vertrag aufrufe). Das Problem liegt in diesem Test

// Should not find user
  it("Should not find user", function(done) {
    patient.getPublicAddress(web3.fromAscii("123456789"), {from:accounts[0], to:patient.address})
    .then(function(res) {
      assert.equal(res, 0);
      done()
    }, function(error) {
        // Force an error if callback fails.
        console.error(error)
        assert.equal(true, false)
        done()
      })
  })

es kehrt zurück Error: VM Exception while processing transaction: invalid opcode. Es gibt diese Frage hier , aber ich habe nicht verstanden, wie sie von dort aus funktioniert (obwohl ich die Zuordnungen in der Registrierung öffentlich gemacht habe).

Antworten (1)

Sie sollten zuerst den Registrierungsvertrag und dann den Benutzer bereitstellen.

Sie können dem Benutzervertrag einen Konstruktor hinzufügen, um ihn regmit der Adresse des Registrierungsvertrags zu instanziieren.

Wenn Sie Ihr Mapping globals machen public, erstellt der Solidity-Compiler automatisch Getter-Funktionen, die zum Testen erforderlich sind.

Der Konstruktor für User würde so aussehen:

function User(address _registry) {
    reg = _registry;
} 

In einer js-Datei für Ihren Trüffeltest können Sie beginnen, indem Sie eine Versprechenskette schreiben, um Ihre Verträge zu erfüllen. (Vorausgesetzt, Sie haben Migrationen für die Verträge zusammengestellt und geschrieben)

const Registry = artifacts.require('./Registry.sol')
const User = artifacts.require('./User.sol')

let registry
let user
let id = '0x...' // bytes 32 id

Registry.new().then((inst) => {
    registry = inst
    return User.new(registry.address)
}).then((inst) => {
    user = inst
    return user.register.call(id)
}).then((res) => {
    return registry.ID.call(id)
}).then((res) => {
    assert.equal(user.address, res)
})
Ich habe es eigentlich zu schnell akzeptiert. Bei mir hat es teilweise funktioniert. Der Vertrag wurde bereitgestellt und ich bekam die Adresse gut zurück. Aber wenn ich versuche, Methoden zu testen, die davon abhängen, erhalte ich den Fehler Error: VM Exception while processing transaction: invalid opcode. Ich habe die Frage so bearbeitet, dass sie das enthält.
@SeanPollock!!! Was geht ab Kumpel?!?!